好的,我们假设一些简单的数据库。 我们有pet table和pet_owner表,pet将其外键链接到pet_owner
pet_owner:
|--id---|-----name-----|
| 1 |Michael Mayers|
| 2 |John Doe |
| 3 |Markus Tsuker |
| 4 |Bob Dilan |
| 5 |Simon Pegg |
pet:
|--id---|----type---|---owner---|---name---|
| 1 | dog | 1 |Billy |
| 2 | cat | 1 |Willy |
| 3 | bird | 1 |Dilly |
| 4 | dog | 2 |Klaus |
| 5 | cat | 2 |Boss |
| 6 | dog | 3 |Shmat |
| 7 | dog | 4 |Corin |
| 8 | fish | 5 |Suzy |
| 9 | dog | 1 |Mars |
所以,简单的任务 - 我需要选择同时拥有CAT和DOG的人。这是分面过滤的一项微不足道的常见任务。
第一种方法:
SELECT
pet_owner.name
FROM pet_owner, pet
WHERE
pet_owner.id = pet.owner AND
pet.type IN ('cat', 'dog')
GROUP BY pet_owner.name
HAVING (COUNT(DISTINCT pet.type) = 2);
第二种方法:
SELECT DISTINCT pet_owner.name
FROM pet_owner, pet T1, pet T2
WHERE pet_owner.id = T1.owner
AND pet_owner.id = T2.owner
AND T1.type = 'cat'
AND T2.type = 'dog';
问题:
答案 0 :(得分:1)
从不在FROM
子句中使用逗号; 始终使用正确的JOIN
语法。这是建议,所以你的代码看起来像是在21世纪写的,与实际问题无关。
这个问题的正常答案是说"试试你的数据,看看哪个更快"。
但是,对于您的特定问题,聚合方法更好。
让我承认偏见。无论如何,我更喜欢聚合方法。只需要对三个宠物进行一次简单的修改即可以改变标准 - 比如需要三只宠物,或者检查鸟类和狗只。甚至,猫和狗,但不是鸟。
在这种情况下更好的原因是select distinct
。无论如何,这基本上都会在连接之上进行聚合。更糟糕的是,人们可以拥有多只宠物,因此连接生成的行数可能会大于原始行数。
事实上,有人可能会有一个小狗工厂,其中有几只宠物猫被扔进去,并且真正使用连接来甩掉查询的性能。小狗工厂对聚合查询的性能影响很小。
如果你的数据开始时是不同的(人们只允许一种类型的宠物)并且你正在寻找两个特定的数据,那么join
查询通常会有更好的表现(它仍然取决于其他因素)数据和数据库优化器)。即便如此,出于上述原因,我仍默认使用这些类型查询的聚合方法。
我还要注意,我在生活中写过一些非常复杂的问题。我不认为我曾经写过一个有1000个连接的连接。如果您正在查看那么多项目,那么GROUP BY
将是您的选择。查询会简单得多。