#mysql #join #group-by #count #distinct
Вопрос:
У меня есть таблица фотографий с подробными фотографиями:
| photoID | photoName |
| ------- | --------- |
| 1 | w |
| 2 | x |
| 3 | y |
| 4 | z |
и еще одна таблица tblФототЕгов тегов к фотографиям:
| photoID | tagID |
| ------- | ----- |
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 3 | 2 |
| 4 | 1 |
| 4 | 2 |
Я пытаюсь сделать пару запросов, которые выберут фотографии с любыми заданными тегами, либо И, либо ИЛИ. В примере предположим, что я ищу фотографии, связанные с тегом 1 И/ИЛИ 2.
ИЛИ следует выбрать все фотографии (1, 2, 3 и 4).
И следует выбрать только 1 и 4.
У меня есть следующее для ИЛИ которое отлично работает:
SELECT DISTINCT tblPhotos.photoID FROM tblPhotos
INNER JOIN tblPhotoTags ON tblPhotos.photoID = tblPhotoTags.photoID
WHERE tblPhotoTags.tagID = 1 OR tblPhotoTags.tagID = 2
Но я изо всех сил пытаюсь понять, как выполнить запрос И.
Комментарии:
1. A
tagID
может иметь только одно значение, поэтомуtagID =1 AND tagID =2
не будет иметь никаких результатов. Либо свяжите второй раз сtblPhotoTags
, либо используйте агрегатные функции.
Ответ №1:
Если вам нужны только идентификаторы фотографий, то нет необходимости присоединяться к tblPhotos
ним .
Для 1 — го случая ( OR
) используйте DISTINCT
и просто WHERE
предложение:
SELECT DISTINCT photoID
FROM tblPhotoTags
WHERE tagID IN (1, 2);
Для 2-го случая ( AND
) используйте агрегацию и установите условие в HAVING
предложении:
SELECT photoID
FROM tblPhotoTags
WHERE tagID IN (1, 2)
GROUP BY photoID
HAVING COUNT(*) = 2 -- the number of tagIDs in the IN list
Если вам также нужно название фотографий, присоединяйтесь к tblPhotos
:
SELECT DISTINCT p.*
FROM tblPhotos p INNER JOIN tblPhotoTags t
ON t.photoID = p.photoID
WHERE t.tagID IN (1, 2);
и:
SELECT p.photoID, p.photoName
FROM tblPhotos p INNER JOIN tblPhotoTags t
ON t.photoID = p.photoID
WHERE t.tagID IN (1, 2)
GROUP BY p.photoID, p.photoName
HAVING COUNT(*) = 2 -- the number of tagIDs in the IN list
Смотрите демонстрацию.
Комментарии:
1. Чрезвычайно полезно. Для упрощения вопроса я немного сократил требования, поэтому мне все еще нужно внутреннее соединение, но затем и ПОДСЧЕТ отлично справляются с работой. Спасибо.
2. Да — все работает идеально. Еще раз спасибо.