Нахождение похожей записи в рамках одной таблицы

Overcast

Новичок
Нахождение похожей записи в рамках одной таблицы

Есть таблица `relations`. Выглядит приблизительно так:
--------------------------
|ID|ITEM_ID|CAT_ID|
--------------------------
|1 |1 |104 |
|2 |1 |108 |
|3 |1 |111 |
|4 |2 |102 |
|5 |2 |108 |
|6 |2 |111 |
|. |. |... |
--------------------------

Это связывающая таблица между таблицами `items` ( ключ ITEM_ID) и `categories` ( ключ CAT_ID ). Каждому объекту (ITEM_ID) присвоено несколько значений категорий (CAT_ID). Возможно с помощью запроса MYSQL вывести все записи ITEM_ID у которых CAT_ID будет равен нескольким значения одновременно (например и 108 и 111, как у записей ITEM_ID 1 и 2)?
 
Автор оригинала: findnext
меню делаешь, да?

-~{}~ 16.12.08 19:25:

IN
Нет, делаю похожие записи для каталога видео. IN не подходит, если я делаю SELECT DISTINCT `item_id` FROM `relations` WHERE `cat_id` IN ( 108, 111 ), то получу записи которые содержат 108 И/ИЛИ 111, а нужно 108 И 111.
 
[sql]SELECT ITEM_ID, GROUP_CONCAT( CAST( CAT_ID AS CHAR )
ORDER BY CAT_ID
SEPARATOR ',' ) AS grp
FROM relations
GROUP BY ITEM_ID
HAVING grp = "108,111"[/sql]

Правда, это решение требует Full table scan. Но думаю, его можно оптимизировать вот так:

[sql]SELECT ITEM_ID, GROUP_CONCAT( CAST( CAT_ID AS CHAR )
ORDER BY CAT_ID
SEPARATOR ',' ) AS grp
FROM (
(

SELECT *
FROM relations
WHERE CAT_ID
IN ( 108, 111 )
) AS tmptbl
)
GROUP BY ITEM_ID
HAVING grp = "108,111"[/sql]
 
Не помогло :( Возвращает пустой результат

P.S. Помогло :) Это я ступил, в grp = "108,111" у меня другие значения, а я их не отсортировал по возрастанию. СПАСИБО ОГРОМНОЕ!
 
Не за что. Только обязательно проверьте, как запросы себя ведут на больших таблицах. Как бы тормозов не наделать.
 
Таблица из 12460 элементов. Реальные запросы и статистика:

SELECT `cinemaid`, GROUP_CONCAT( CAST( `catid` AS CHAR ) ORDER BY `catid` SEPARATOR ',' ) AS grp FROM `catalog_categories` GROUP BY `cinemaid` HAVING grp = "40,102,109,110,112,132,133,144,170"

Отображает строки 0 - 0 (1 всего, запрос занял 0.0249 сек.)

SELECT `cinemaid`, GROUP_CONCAT( CAST( `catid` AS CHAR ) ORDER BY `catid` SEPARATOR ',' ) AS grp FROM ( ( SELECT * FROM `catalog_categories` WHERE `catid` IN ( 40, 102, 109, 110, 112, 132, 133, 144, 170 ) ) AS tmptbl ) GROUP BY `cinemaid` HAVING grp = "40,102,109,110,112,132,133,144,170"

Отображает строки 0 - 0 (1 всего, запрос занял 0.0127 сек.)

Второй вариант действительно быстрее! Сервер довольно мощный, так что сложно судить по скорости %) Но на всякий пожарный кеширую полученный результат на 30 дней :)
 
Сверху