Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
Страницы: (2) [1] 2  ( Перейти к первому непрочитанному сообщению )  
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> SQL: поиск отсутствующих
FatCat  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Чеширский кот
******

Профиль
Журнал
Группа: Администратор
Почтальон группы
Сообщений: 6044
Пользователь №: 1
На форуме: 11 лет, 5 месяцев, 13 дней
Карма: 129

Не пью :
22 года, 10 месяцев, 13 дней


Не знаю как сформулировать запрос чтобы погуглить...
Есть связанные таблицы. Например таблица товаров и таблица отзывов покупателей.
Таблицы
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...


--------------------
Бесплатному сыру в дырки не заглядывают...
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
redreem  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 4284
Пользователь №: 29002
На форуме: 5 лет, 11 месяцев, 19 дней
Карма: 147




SELECT i.*
FROM item i
LEFT JOIN comment c ON(c.item_id=i.id)
WHERE
c.id is null
group by

i.id


если это формально и "перебор", но как показывает практика - отрабатывается очень быстро.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
waldicom  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 6277
Пользователь №: 5552
На форуме: 9 лет, 13 дней
Карма: 164




select id from item where id not in (select distinct item_id from comment)
?


--------------------
Свои мозги еще никто не отменял.
Телепатов нету.
PM
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
FatCat  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Чеширский кот
******

Профиль
Журнал
Группа: Администратор
Почтальон группы
Сообщений: 6044
Пользователь №: 1
На форуме: 11 лет, 5 месяцев, 13 дней
Карма: 129

Не пью :
22 года, 10 месяцев, 13 дней


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


--------------------
Бесплатному сыру в дырки не заглядывают...
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
FatCat  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Чеширский кот
******

Профиль
Журнал
Группа: Администратор
Почтальон группы
Сообщений: 6044
Пользователь №: 1
На форуме: 11 лет, 5 месяцев, 13 дней
Карма: 129

Не пью :
22 года, 10 месяцев, 13 дней


waldicom
Опередил на несколько секунд. biggrin.gif

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


--------------------
Бесплатному сыру в дырки не заглядывают...
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
redreem  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 4284
Пользователь №: 29002
На форуме: 5 лет, 11 месяцев, 19 дней
Карма: 147




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

на c.item_id индекс не забудь.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
FatCat  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Чеширский кот
******

Профиль
Журнал
Группа: Администратор
Почтальон группы
Сообщений: 6044
Пользователь №: 1
На форуме: 11 лет, 5 месяцев, 13 дней
Карма: 129

Не пью :
22 года, 10 месяцев, 13 дней


Цитата (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...


--------------------
Бесплатному сыру в дырки не заглядывают...
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Kusss  
Дата
Цитировать сообщение

Пользователь сейчас на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 1603
Пользователь №: 28976
На форуме: 5 лет, 11 месяцев, 21 день
Карма: 100




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 уникальных).
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
redreem  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 4284
Пользователь №: 29002
На форуме: 5 лет, 11 месяцев, 19 дней
Карма: 147




Цитата
забрать обе таблицы в массивы, и обсчитывть в php

у меня тут проектик, где как раз чел выгружал все в пых и там сортировал, так вот в определенных условиях пых тупо по памяти ложился. по-любому можно на sql все разогнать до приемлимого. задачка-то тривиальная.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
redreem  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 4284
Пользователь №: 29002
На форуме: 5 лет, 11 месяцев, 19 дней
Карма: 147




Цитата
Попробовал.
С джойном: 0.2494 сек
С подзапросом: 0.2497 сек

попробуй раз в 10 увеличить количество данных и проверь. возможно время вовсе в 10 раз не увеличится.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
FatCat  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Чеширский кот
******

Профиль
Журнал
Группа: Администратор
Почтальон группы
Сообщений: 6044
Пользователь №: 1
На форуме: 11 лет, 5 месяцев, 13 дней
Карма: 129

Не пью :
22 года, 10 месяцев, 13 дней


Уже сделал. Группы и контактная информация:
$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 мегабайт в запасе у меня точно есть, а миллиона айдишников точно не будет.


--------------------
Бесплатному сыру в дырки не заглядывают...
PMПисьмо на e-mail пользователюICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Invis1ble  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме




******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 11965
Пользователь №: 23195
На форуме: 6 лет, 11 месяцев, 26 дней
Карма: 435

Трезвый :
7 лет, 10 месяцев, 26 дней


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

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


--------------------
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
redreem  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 4284
Пользователь №: 29002
На форуме: 5 лет, 11 месяцев, 19 дней
Карма: 147




Цитата (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 появляются непонятки. ругается.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
chee  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Сын полка
Сообщений: 1967
Пользователь №: 38654
На форуме: 3 года, 6 месяцев, 17 дней
Карма: 46




комментариев может быть много, товаров обычно не много, поэтому логично делать выборку по товарам

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

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


--------------------
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации

Мой блог
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Guest  
Дата
Цитировать сообщение


Гость пожелал остаться неизвестным

Unregistered









Цитата (chee @ 3.04.2016 - 21:22)
Не проверял, но логика должна быть ясна

Ужс...
Есть же NOT EXISTS.
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темыСтраницы: (2) [1] 2  Ответ в темуСоздание новой темыСоздание опроса