[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: SQL: поиск отсутствующих
Страницы: 1, 2
FatCat
Не знаю как сформулировать запрос чтобы погуглить...
Есть связанные таблицы. Например таблица товаров и таблица отзывов покупателей.
Таблицы
CREATE TABLE `item` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`txt` text NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;

CREATE TABLE `comment` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`item_id` int(10) NOT NULL,
`comment` text NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=1 ;
Когда генерируется страница товара с отзывами, таблица отзывов джойнится:
Запрос
SELECT i.* , c.comment
FROM item i
LEFT JOIN comment c ON(c.item_id=i.id)
WHERE i.id=1
Здесь всё просто.


Возникла потребность собрать список товаров, у которых еще нет комментариев.
Не соображу, как это сделать без перебора всей таблицы item...

_____________
Бесплатному сыру в дырки не заглядывают...
redreem
SELECT i.*
FROM item i
LEFT JOIN comment c ON(c.item_id=i.id)
WHERE
c.id is null
group by

i.id


если это формально и "перебор", но как показывает практика - отрабатывается очень быстро.
waldicom
select id from item where id not in (select distinct item_id from comment)
?

_____________
Свои мозги еще никто не отменял.
Телепатов нету.
FatCat
Я думал над вариантом:
SELECT id FROM item WHERE id NOT IN(
SELECT item_id FROM comment
)
Но здесь перебор всей таблицы comment...

_____________
Бесплатному сыру в дырки не заглядывают...
FatCat
waldicom
Опередил на несколько секунд. biggrin.gif

Попробую погонять на реальной БД с большим числом строк, посмотреть что быстрее будет работать.

_____________
Бесплатному сыру в дырки не заглядывают...
redreem
Цитата (FatCat @ 3.04.2016 - 17:15)
Попробую погонять на реальной БД с большим числом строк, посмотреть что быстрее будет работать.

на c.item_id индекс не забудь.
FatCat
Цитата (redreem @ 3.04.2016 - 15:19)
индекс не забудь

Несомненно.


Попробовал.
С джойном: 0.2494 сек
С подзапросом: 0.2497 сек
Таблица items 739 записей.
Таблица comments 1746 записей.


При этом просто прогон таблиц намного быстрее:
select id from item - 0.0016 сек
select distinct item_id from comment - 0.0021 сек

Получается, быстрее всего будет забрать обе таблицы в массивы, и обсчитывть в php...

_____________
Бесплатному сыру в дырки не заглядывают...
Kusss
FatCat
Очень странно.
Цитата (waldicom @ 3.04.2016 - 15:14)
select id from item where id not in (select distinct item_id from comment)

Этот запрос у меня обработался "Отображает строки 0 - 29 ( 1,049 всего, Запрос занял 0.0016 сек.)"
~6к заказов, ~20.6к комментариев (5150 уникальных).
redreem
Цитата
забрать обе таблицы в массивы, и обсчитывть в php

у меня тут проектик, где как раз чел выгружал все в пых и там сортировал, так вот в определенных условиях пых тупо по памяти ложился. по-любому можно на sql все разогнать до приемлимого. задачка-то тривиальная.
redreem
Цитата
Попробовал.
С джойном: 0.2494 сек
С подзапросом: 0.2497 сек

попробуй раз в 10 увеличить количество данных и проверь. возможно время вовсе в 10 раз не увеличится.
FatCat
Уже сделал. Группы и контактная информация:
$return = array();
$DB->query("SELECT grid FROM groups");
while($row = $DB->fetch_row())$return[$row['grid']] = $row['grid'];
$DB->query("SELECT DISTINCT group_id FROM contacts");
while($row = $DB->fetch_row())unset($return[$row['group_id']]);



Цитата (redreem @ 3.04.2016 - 15:52)
в определенных условиях пых тупо по памяти ложился

Мне это не грозит.
Максимальный размер айдишника - 10 байт. Один элемент массива, соответственно, максимум 20 байт. Массив из миллиона айдишников съест максимум 20 мегабайт.
20 мегабайт в запасе у меня точно есть, а миллиона айдишников точно не будет.

_____________
Бесплатному сыру в дырки не заглядывают...
Invis1ble
Цитата (FatCat @ 3.04.2016 - 18:24)
Массив из миллиона айдишников съест максимум 20 мегабайт.

ошибаешься
в php массивы занимают гораздо больше памяти, чем собственно их содержимое

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

redreem
Цитата (FatCat @ 3.04.2016 - 19:24)
Уже сделал. Группы и контактная информация:
$return = array();
$DB->query("SELECT grid FROM groups");
while($row = $DB->fetch_row())$return[$row['grid']] = $row['grid'];
$DB->query("SELECT DISTINCT group_id FROM contacts");
while($row = $DB->fetch_row())unset($return[$row['group_id']]);



Цитата (redreem @ 3.04.2016 - 15:52)
в определенных условиях пых тупо по памяти ложился

Мне это не грозит.
Максимальный размер айдишника - 10 байт. Один элемент массива, соответственно, максимум 20 байт. Массив из миллиона айдишников съест максимум 20 мегабайт.
20 мегабайт в запасе у меня точно есть, а миллиона айдишников точно не будет.

кстати если ансетить элементы массива, то потом в foreach появляются непонятки. ругается.
chee
комментариев может быть много, товаров обычно не много, поэтому логично делать выборку по товарам

SELECT i.*
FROM (
SELECT i.*, IF((SELECT id FROM comments AS c WHERE c.item_id = id LIMIT 1), 1, 0) AS exist_comment
FROM item AS i
) AS i
WHERE i.exist_comment = 0

Не проверял, но логика должна быть ясна

_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
Guest
Цитата (chee @ 3.04.2016 - 21:22)
Не проверял, но логика должна быть ясна

Ужс...
Есть же NOT EXISTS.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.