MySQL - SELECT, убрать дубли, оптимизировать при 2х JOIN

Статус
В этой теме нельзя размещать новые ответы.
Так... У меня в БД 100 000 строк... Контактов около 8 000 000 к ней...

Вы правда думаете, что ПЫХ быстрее обработает 8 000 000 записей, чем MySQL? Да Вы ржоте чтоль? Оперативка квакнется на первом ляме...
 
Вообще-то чтобы выбрать без дублей, используется Для просмотра ссылки Войди или Зарегистрируйся
Или я не совсем понял задачу.
 
Последнее редактирование:
Есть запрос:
Код:
SELECT
`u`.*,
`c`.`title` AS `city`,
`p`.`title` AS `phone`
FROM
`clients` AS `u`
LEFT JOIN
(SELECT `title`, `client_id` FROM `clients_contacts` WHERE `type` = 1) AS `c`
ON
`u`.`id` = `c`.`client_id`
LEFT JOIN
(SELECT `title`, `client_id` FROM `clients_contacts` WHERE `type` = 3) AS `p`
ON
`p`.`client_id` = `u`.`id`;

Нужно оптимизировать и убрать дубли...

В настоящий момент если у человека 2 телефона и 2 города (типы 3 и 1 соответственно) - происходит вывод 4 строк, а надо выводить только 2...

Так же по возможности реализовать с минимальной нагрузкой на БД.

P.s. этот запрос работает, но выводит слишком много лишнего :) При 100 городах и 100 телефонах у 1 клиента будет 10 000 строчек на 1 человека, а надо 100.

уоу уоу полегче ))) попробу

select distinct
u.*,
c.title as 'city',
b.title as 'phone'
from clients as a
left join clients_contacts as b on a.id = b.client.id
left join clients_contacts as c on a.id = c.client.id
where b.type = 1 and c.type =3
group by a.id
 
Народ, ну Вы хоть сами попробуйте свои SQL выполнять... Пишите охинею...

konov,
1) ошибка синтаксиса, таблицы `u` не существует
2) group by a.id - выводится 1 строка на каждого клиента, а надо по максимальному количеству городов или телефонов
3) where b.type = 1 and c.type =3 А если нет ни города, ни телефона - клиент в выборку не попадёт вообще

И это я могу написать не выполняя скул. Если выполнить - там ещё пару багов всплывёт.

Denixxx,
простите, а куда пихать изволите? После первого SELECT? Ровным счётом ничего не даёт...

balabolka,
мне ровным счётом побоку сколько временных таблиц MySQL создаст... Я могу ей сказать создать ещё больше... Для ляма записей это всё равно быстрее, чем на PHP.

cthulchu,
зачем Вам дамп базы? Получить базу клиентов? :)
Пример есть... В конкретном примере выводится 5 строчек (по первому клиенту 4), надо сделать 3 (по первому - 2). Но если очень хотите - добавил в первый пост выгрузку больше... Добавил второй пример ошибки, когда строка не выводится с примерами в теме
 
Последнее редактирование:
Код:
SELECT
`u`.*,
`c`.`title` AS `city`,
`p`.`title` AS `phone`
FROM
`clients` AS `u`, `clients_contacts` AS `c`, `clients_contacts` AS `p` WHERE `c`.`type` = 1 AND `u`.`client_id` = `p`.`client_id` AND `c`.`client_id` = `p`.`client_id` AND `p`.`type` = 3
GROUP BY `p`.`id`

Рабочий вариант
Код:
SELECT
`u`.*,
`s`.`city` AS `city`,
`s`.`phone` AS `phone`
FROM `clients` AS `u`,
(SELECT `c`.`client_id` AS `id`, `c`.`title` AS `city`, `p`.`title` AS `phone` FROM clients_contacts as `c`
LEFT OUTER JOIN clients_contacts AS `p` ON `c`.`client_id` = `p`.`client_id` AND `p`.`type` = 3
WHERE `c`.`type` = 1
GROUP BY `id`, `phone`
UNION
SELECT `c`.`client_id` AS `id`, `c`.`title` AS `city`, `p`.`title` AS `phone` FROM clients_contacts as `c`
RIGHT OUTER JOIN clients_contacts AS `p` ON `c`.`client_id` = `p`.`client_id` AND `p`.`type` = 3
WHERE `c`.`type` = 1
GROUP BY `id`, `phone`) AS `s`
WHERE `s`.`id` = `u`.`id`
GROUP BY `id`,`city`, `phone`
 
Последнее редактирование модератором:
Народ, ну Вы хоть сами попробуйте свои SQL выполнять... Пишите охинею...

konov,
1) ошибка синтаксиса, таблицы `u` не существует
2) group by a.id - выводится 1 строка на каждого клиента, а надо по максимальному количеству городов или телефонов
3) where b.type = 1 and c.type =3 А если нет ни города, ни телефона - клиент в выборку не попадёт вообще

И это я могу написать не выполняя скул. Если выполнить - там ещё пару багов всплывёт.

Denixxx,
простите, а куда пихать изволите? После первого SELECT? Ровным счётом ничего не даёт...

balabolka,
мне ровным счётом побоку сколько временных таблиц MySQL создаст... Я могу ей сказать создать ещё больше... Для ляма записей это всё равно быстрее, чем на PHP.

cthulchu,
зачем Вам дамп базы? Получить базу клиентов? :)
Пример есть... В конкретном примере выводится 5 строчек (по первому клиенту 4), надо сделать 3 (по первому - 2). Но если очень хотите - добавил в первый пост выгрузку больше... Добавил второй пример ошибки, когда строка не выводится с примерами в теме

сорри, вместо u давайте поставим a
ну по поводу второго пункта я бы поспорил,
а по третьему, уважаемый, если нет телефона, вот поэтому и left join

вы прежде чем тут всех критиковать, покажите свой запрос???
 
konov, так я ж показывал уже в первом посте )))
Про ахинею не к Вам относилось... Сори...

Второй пункт, к сожалению, так и будет... GROUP BY `id` говорит, что необходимо соединить все строчки с 1 id в 1 строку... А мне нужно получить в данном случае 2 строки с одинаковым id. При GROUP BY `id` это не получится сделать...

По третьему... Смотрите, у SQL есть такая неприятная особенность - если писать WHERE, то это условие главнее, чем LEFT JOIN. Соответственно, если мы указываем чётко where b.type = 1, то MySQL вернёт строку только в том случае, если b.type = 1 составляющая существует... А это мне не подходит, к сожалению. Так что LEFT JOIN не отработает, т.к. условие WHERE более жёсткое... Впрочем, запрос примерно такой, как у Вас я уже делал и сам, не помогло... Но всё равно спасибо.

А про ахинею было в сторону "А давайте на пхп перенесём", "а дайте больше примеров" и т.д. Ваш вариант, если нет БД под рукой, я бы и сам предложил, так что в любом случае спасибо за попытку...

Girt, а вот это идея! GROUP BY `p`.`id` - чёт такой вариант в бошку не приходил... Может сработать... В 2 часа ночи запустить интерпретатор в голове не получается, а базы под рукой нет, предсказать поведение MySQL не могу, но явно что-то хорошее в этом есть...

------------------------

P.s. на самом деле проблему уже решил 2 запросами и небольшой обработкой на пхп... Но там ТЗ поменялось как всегда и под новое - прокатило... Теперь уже для себя стало интересно сделать 1 запросом ))))
 
Лучше всё-таки делать вот так:
Код:
SELECT
`u`.*,
`s`.`type` AS `type`,
`s`.`title` AS `contact`
FROM `clients` AS `u`,  `clients_contacts` AS `s`
WHERE `u`.`id` = `s`.`client_id` AND `s`.`type` = 1
UNION
SELECT
`u`.*,
`s`.`type` AS `type`,
`s`.`title` AS `contact`
FROM `clients` AS `u`,  `clients_contacts` AS `s`
WHERE `u`.`id` = `s`.`client_id` AND `s`.`type` = 3
Получаем одним запросом, нет сложных соединений и подзапросов, в результате нет повторений (кол-во строк = кол-во городов + кол-во телефонов по каждому пользователю).
 
UNION разве не в столбец соединяет? Мне нужно в строку...
 
Да, получается в одной строке, или телефон, или город.
При различном кол-ве городов и телефонов, при выводе в одну строку будут попадаться NULL.
Еще один вариант: по одной строке на пользователя, в одном поле собираем все города, в другом все телефоны, думаю попроще в реализации будет.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху