开发者

SQL: Query one table based on join on another table that has multiple matches

If I had two database tables like this:

+-----------------+
| dog     开发者_如何学编程        |
+-----------------+
| id              |
| name            |
| size            |
+-----------------+

+-----------------+
| dog_color       |
+-----------------+
| id              |
| dog_id          |
| color           |
+-----------------+

How would I write a query such that the result returned all dogs that had the colors of black and white? The dog could have other colors too but needs to have both black and white.


Tested solution below using MySQL 5.1.x, returns all dogs that have at least white AND black colors:

SELECT dog.*,
       group_concat(dc_all.color) AS colors
FROM dog
JOIN dog_color as dc_white on (dog.id = dc_white.dog_id AND dc_white.color = 'white')
JOIN dog_color as dc_black on (dog.id = dc_black.dog_id AND dc_black.color = 'black')
LEFT JOIN dog_color as dc_all on (dog.id = dc_all.dog_id);


select dog.*, count(dog_color.color) as num_colors from dog
inner join dog_color on dog_color.dog_id = dog.id
where color in ('black', 'white')
group by dog.id
HAVING COUNT(DISTINCT dog_color.color) = 2;

should do the trick.

Sample data and test:

mysql> select * from dog; 
+------+-------+------+
| id   | name  | size |
+------+-------+------+
|    1 | fido  |    0 |
|    2 | ruff  |    0 |
|    3 | rover |    0 |
+------+-------+------+
3 rows in set (0.00 sec)

mysql> select * from dog_color;
+------+--------+-------+
| id   | dog_id | color |
+------+--------+-------+
|    1 |      1 | black |
|    2 |      1 | white |
|    3 |      1 | brown |
|    4 |      2 | black |
|    5 |      3 | white |
+------+--------+-------+
5 rows in set (0.00 sec)

mysql> select dog.*, count(dog_color.color) as num_colors from dog
    -> inner join dog_color on dog_color.dog_id = dog.id
    -> where color in ('black', 'white')
    -> group by dog.id
    -> having num_colors = 2;
+------+------+------+------------+
| id   | name | size | num_colors |
+------+------+------+------------+
|    1 | fido |    0 |          2 |
+------+------+------+------------+
1 row in set (0.00 sec)


select distinct
  d.id
  , d.name
  , d.size
from
  dog d
  inner join dog_color c1
    on d.id = c1.dog_id 
    and c1.color in ('white')
  inner join dog_color c2
    on d.id = c2.dog_id 
    and c2.color in ('black')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜