#mysql #sql
#mysql #sql
Вопрос:
Я пытаюсь избавиться от ржавчины в своих навыках SQL и нуждаюсь в некоторой помощи со следующим запросом. База данных, которую я сейчас использую, — mysql.
Я хочу получить все карточки, которым присвоены КАК ‘tag2’, так и ‘tag4’. На основе содержимого существующей таблицы (как видно из приведенного ниже отрывка) запрос должен возвращать две строки: FlashCard_ID 1 и 2.
Как бы я сформулировал этот запрос? Прошло некоторое время с тех пор, как мне приходилось делать что-то подобное.
mysql> select * from flashcard;
-------------- ------------ ----------
| FLASHCARD_ID | QUESTION | ANSWER |
-------------- ------------ ----------
| 1 | Question 1 | Answer 1 |
| 2 | Question 2 | Answer 2 |
| 3 | Question 3 | Answer 3 |
-------------- ------------ ----------
3 rows in set (0.00 sec)
mysql> select * from tag;
-------- ------
| TAG_ID | NAME |
-------- ------
| 1 | tag1 |
| 2 | tag2 |
| 3 | tag3 |
| 4 | tag4 |
| 5 | tag5 |
-------- ------
5 rows in set (0.00 sec)
mysql> select * from flashcard_tags;
-------- --------------
| TAG_ID | FLASHCARD_ID |
-------- --------------
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 2 | 2 |
| 4 | 2 |
| 5 | 2 |
-------- --------------
6 rows in set (0.00 sec)
Ответ №1:
SELECT f.*
FROM (
SELECT flashcard_id
FROM tags t
JOIN flashcard_tags ft
ON ft.tag_id = t.tag_id
WHERE t.name IN ('tag2', 'tag4')
GROUP BY
flashcard_id
HAVING COUNT(*) = 2
) ft
JOIN flashcard f
ON f.flashcard_id = ft.flashcard_id
Комментарии:
1. Спасибо. Это работает. Мне интересно, возможно ли это сделать без предложения Having?
2. Можем ли мы использовать следующий запрос? Пожалуйста, поправьте меня, если я сделал что-то не так.
3. «ВЫБЕРИТЕ flashId ИЗ flashcards_tags, ГДЕ tag_id = 2 И СУЩЕСТВУЕТ (ВЫБЕРИТЕ flashId ИЗ flashcards_tags, ГДЕ tag_id = 4)»
4. @Sandeep: ваш подзапрос не коррелирован.
Ответ №2:
SELECT f.*
FROM flashcard f
INNER JOIN flashcard_tags ft1 ON f.FLASHCARD_ID = ft1.FLASHCARD_ID
INNER JOIN tag t1 ON ft1.TAG_ID = t1.TAG_ID AND t1.NAME = 'tag2'
INNER JOIN flashcard_tags ft2 ON f.FLASHCARD_ID = ft2.FLASHCARD_ID
INNER JOIN tag t2 ON ft2.TAG_ID = t2.TAG_ID AND t2.NAME = 'tag4'
Комментарии:
1. спасибо за ваш ответ, но я не могу заставить этот запрос возвращать какие-либо строки
2. @Justin: Это потому, что я сначала неправильно понял, извините. Теперь проблем быть не должно.
Ответ №3:
Вот еще один запрос, который работает. Этот не использует подзапрос, и это то, что я в конечном итоге использовал в своем коде гибернации.
select fc.FLASHCARD_ID,
fc.QUESTION,
fc.ANSWER
from FLASHCARD fc
inner join FLASHCARD_TAGS fc_t
on fc.FLASHCARD_ID=fc_t.FLASHCARD_ID
inner join TAG t
on fc_t.TAG_ID=t.TAG_ID
where t.Name in ('tag2', 'tag4')
group by fc.FLASHCARD_ID
having count(t.TAG_ID)=2