2012-01-23 4 views
2

Пожалуйста, помогите сделать запрос.Данные фильтра из двух таблиц

Есть две таблицы, artist и album. Я хочу выбрать только тех художников, чьи альбомы содержат изображение. То есть, если у актера есть 10 альбомов и только один из них имеет изображение или не содержит, я хочу, чтобы пропустить (только если все альбомы исполнителя размещены фото)

стол художника:

artist_id 
---------| 
1  | 
2  | 

стол альбомы:

artist_id | album_id | picture_id 
--------------------------------- 
1   | 122... | true 
1   | 123... | false 
2   | 124... | true 
2   | 125... | true 

Итак, я хочу, чтобы выбрать только группа, где artist_id=2 (потому что все альбомы есть фотографии);

ответ

6

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

SELECT 
    * 
FROM 
    artist a 
WHERE 
    artist_id NOT IN 
    (SELECT DISTINCT artist_id FROM album WHERE picture_id = false); 

EDIT:
Если вы сохранили исполнителей без альбомов, их тоже нужно исключить (ознакомьтесь с комментариями для объяснения). в этом случае, вам придется добавить что-то вроде:

AND 
    1 <= (SELECT COUNT(*) FROM album WHERE artist_id = a.artist_id) 
+1

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

+0

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

+0

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

4

Вы можете использовать пункт GROUP BY найти количество альбомов художников. Затем вы можете сравнить этот счет с подсчетом . Агрегатные функции могут быть использованы внутри HAVING пункта, чтобы исключить группы:

SELECT artist_id 
FROM albums 
GROUP BY artist_id 
HAVING COUNT(1) = COUNT(CASE WHEN picture_id THEN 1 ELSE NULL END) 

Полный пример:

SELECT artist.artist_id, artist.name 
FROM artist 
INNER JOIN albums ON artist.artist_id = albums.artist_id 
GROUP BY artist.artist_id, artist.name 
HAVING COUNT(album_id) = COUNT(CASE WHEN picture_id THEN 1 ELSE NULL END) 
+0

, если у исполнителя 1 есть один альбом с одним и без картинки, это будет присутствует в вашем наборе результатов, но не должен, поэтому это не работает должным образом. – oezi

+0

Нет, это не покажет таких художников. –

+0

+1 - Извините, вы правы - я пропустил ваш запрос в первом чтении. – oezi

0

Другое решение, без подзапросов, используя оператор MIN() - если минимальное значение ИСТИНА, то все значения истинны:

SELECT artists.artist_id,MIN(picture_id) 
FROM artists 
INNER JOIN albums ON artists.artist_id = albums.artist_id 
GROUP BY artists.artist_id 
HAVING MIN(IFNULL(picture_id, 0)) > 0 

EDIT

Mod ified запрос, чтобы заменить нулевые значения на 0 в операнде MIN(), он будет таким же чистым.

+0

Я не знаю, им просто интересно .. Что произойдет 1. если picture_id имеет NULL или 2. picture_id имеет '' (Empty String)? – Jayy

+0

Он обрабатывает его правильно. Однако мы не знаем тип столбца «picture_id». Если это INT, он не может содержать пустую строку – tpolyak

0
$sql = mysql_query("SELECT DISTINCT table1.id, table2.id, table2.name 
FROM table1, table2 WHERE id=id GROUP BY name"); 

Попробуйте это. Конечно, это работает. Приветствия !!!

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