2013-04-02 3 views
1

Я искал в SO для некоторых из следующих запросов, но я не могу найти что-то, что соответствует моему поиску, и я немного потерял между IN, INNER JOIN и LEFT JOIN, чтобы написать их.SQL-запросы, связанные с отношениями нескольких связанных тегов и элементов

текущие отношения базы данных enter image description here

1. Получить предметы по тэгам

TAG.url являются струны получили от $_GET, поэтому не INT идентификаторами.

Например, с адресом mydomain/items/tag1+tag2/ у нас будут следующие запросы.

Для одного тега, который был легко, но для двух или более, следующее не похоже на работу в MySql:

SELECT 
    ITEM.id AS 'item_id', 
    ITEM.title AS 'item_title', 
    ITEM.content AS 'item_content' 
    FROM ITEM, ITEM_TAG, TAG 
WHERE 
    (ITEM.id=ITEM_TAG.id_item AND TAG.id=ITEM_TAG.id_dtag AND TAG.url='tag1') 
AND 
    (ITEM.id=ITEM_TAG.id_item AND TAG.id=ITEM_TAG.id_dtag AND TAG.url='tag2') 
... 
AND 
    (ITEM.id=ITEM_TAG.id_item AND TAG.id=ITEM_TAG.id_dtag AND TAG.url='tagn') 

Это один работает:

SELECT 
    ITEM.id AS 'item_id', 
    ITEM.title AS 'item_title', 
    ITEM.content AS 'item_content' 
FROM ITEM 
    INNER JOIN TAG TAG1 
    ON TAG1.url='tag1' 
    INNER JOIN ITEM_TAG ITEM_TAG1 
    ON ITEM_TAG1.id_item=ITEM.id AND ITEM_TAG1.id_tag=TAG1.id 
    INNER JOIN TAG TAG2 
    ON TAG2.url='tag2' 
    INNER JOIN ITEM_TAG ITEM_TAG2 
    ON ITEM_TAG2.id_item=ITEM.id AND ITEM_TAG2.id_tag=TAG2.id 
    ... 
    INNER JOIN TAG TAGn 
    ON TAG2.url='tagn' 
    INNER JOIN ITEM_TAG ITEM_TAGn 
    ON ITEM_TAGn.id_item=ITEM.id AND ITEM_TAGn.id_tag=TAGn.id 

На данный момент, является там лучший способ сделать это, чем те INNER JOIN и ON?

2. Получить соответствующие метки для других тегов

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

Например, давайте представим следующие приборы:

ITEM_TAG    TAG 
id_item | id_tag  id | url 
1  | 1   1 | tag1 
1  | 2   2 | tag2 
1  | 3   3 | tag3 
1  | 4   4 | tag4 
2  | 1 
2  | 2 
2  | 3 
3  | 1 
3  | 2 

Всегда со следующим поиском mydomain/items/tag1+tag2/.

Я хочу показать другие теги с отношением к некоторым элементам (если эти отношения существуют).

Я сожалею, чтобы сказать, что я не имею ни малейшего представления о том, как сделать запрос, который будет выводить следующее:

TAG 
url count(id_item) 
tag3 | 2 
tag4 | 1 

Как получить этот результат?

Редактировать

Я попытался следующие которым, кажется, работает:

SELECT 
    COUNT(id_item) AS 'nb_item', 
    TAG.url AS 'tag_url' 
FROM ITEM_TAG, TAG 
WHERE 
url NOT IN ('tag1','tag2') 
AND id_item IN 
(
    SELECT id_item FROM ITEM_TAG, TAG 
    WHERE url IN ('tag1','tag2') AND id_tag=id 
) 
AND id_tag=id 
GROUP BY TAG.id ORDER BY nb_item DESC 

Любая идея или посоветовать, чтобы оптимизировать это будет значительно appriciated.

+0

Первый из них может быть сделано с помощью подзапроса ....... Выберите идентификатор, название, содержание из пункта, где идентификатор в (выберите id_item из Item_tag где id_tag ​​в (выберите id из тега, где url in ('tag1', 'tag2'))) –

+0

Это лучший способ, чем ответить Andomar? – Valky

+0

Я думаю, что присоединение займет много времени и пространства, чем это ..... вот почему я дал решение с подзапросом –

ответ

2

1. Получить предметы по тэгам

select i.id 
,  i.title 
,  i.content 
from item i 
join item_tag it 
on  i.id = it.id_item 
join tag t 
on  t.id = it.id_tag 
where t.url in ('tag1', 'tag2') 

2.Получить соответствующие метки для других тегов

select t2.url 
,  count(it2.id_item) 
from tag t1 -- this tag 
join item_tag it1 
on  t1.id = it.id_tag 
join item_tag it2 -- other tag for same item 
on  it2.item_id = it1.item_id 
join tag t2 
on  t2.id = it2.id_tag 
where t1.url in ('tag1', 'tag2') 
     and t2.url not in ('tag1', 'tag2') 
group by 
     t2.url 
+0

Спасибо за ваш ответ. Но после тестирования второго решения он выводит только один тег (по моему примеру, он может выводить: «tag3» и «tag4»). – Valky

+0

Смотрите мое редактирование, оно работает на основе вашего 'NOT IN', если вы видите лучшее решение, которое мне известно. +1 в любом случае – Valky

Смежные вопросы