在这种情况下,SQL计数(distinct)是如何工作的



我正在努力寻找德国队对阵波兰队的比赛编号。这是来自https://www.w3resource.com/sql-exercises/soccer-database-exercise/sql-subqueries-exercise-soccer-database-4.php.有两个表:match_details和soccer_country。我不明白计数(distinct(在这种情况下是如何工作的。有人能澄清一下吗?谢谢

SELECT match_no 
FROM match_details 
WHERE team_id = (
SELECT country_id 
FROM soccer_country 
WHERE country_name = 'Germany') 
OR team_id = (
SELECT country_id 
FROM soccer_country 
WHERE country_name = 'Poland') 
GROUP BY match_no 
HAVING COUNT(DISTINCT team_id) = 2;

正如Lamak所提到的,对于一个查询来说,这是一个多么丑陋的考虑因素,但有很多方法可以处理查询。

如前所述,计算(Distinct team_id(可以确保只有2个唯一的团队。如果有笛卡尔结果,您可以得到多行的重复,显示两个团队的多个实例。因此,TEAM_ID上的distinct计数消除了这一点。

现在,也就是说,其他";团队;我看到的查询数据结构有一个比赛的记录和一个参加比赛的每个团队的列。从长远来看,这更容易,但仍然是一个相对容易的查询。

将查询分解一点,并考虑一组大规模的数据(这并不是说,或者任何类型的职业联赛都会有如此大的记录数,从而导致sql引擎的延迟(。

你的第一个标准是与德国队比赛。所以让我们从这个开始。

SELECT 
md1.match_no 
FROM 
match_details md1
JOIN soccer_country sc1
on md1.team_id = sc1.country_id
AND sc1.country_name = 'Germany'

那么,如果德国队没有参加任何一方的比赛,为什么还要看看其他记录/比赛呢。其中这本身将从51个匹配的样本数据中返回6个匹配。所以现在,你所需要做的就是再次加入比赛详情表,只参加那些比赛,但第二支球队是波兰

SELECT 
md1.match_no 
FROM 
match_details md1
JOIN soccer_country sc1
on md1.team_id = sc1.country_id
AND sc1.country_name = 'Germany'
-- joining again for the same match Germany was already qualified
JOIN match_details md2
on md1.match_no = md2.match_no
-- but we want the OTHER team record since Germany was first team
and md1.team_id != md2.team_id
-- and on to the second country table based on the SECOND team ID
JOIN soccer_country sc2
on md2.team_id = sc2.country_id
-- and the second team was Poland
AND sc2.country_name = 'Poland'

是的,这可能是一个更长的查询,但通过消除45个其他匹配(再次考虑大型数据库(,您已经将大量的数据保存到了一个非常有限的集合中。现在只完成了德国/波兰的比赛。没有聚合、计数、区分,只有直接连接。

反馈

让我们来看看一些坏的样本数据。。。正如所有程序员都知道的那样,根本不存在这样的东西(NOT(。无论如何,让我们来看看这几场比赛。

Match    Team ID    blah
52       Poland     Just put the names here for simplistic purposes
52       Poland
53       Germany
53       Germany

如果你在没有DISTINCT团队的情况下运行查询,那么第52场和第53场比赛都会出现。。。波兰队是一支球队,在第52场比赛中出场2次,同样,德国队在第53场比赛中也出场2次。通过执行DISTINCT团队,您可以看到,对于每场比赛,只有一支球队被退回,因此被排除在外。这有帮助吗?同样,没有坏数据:(

还有另一场样本赛,超过2支球队创建了

Match    Team ID    
54       France     
54       Poland
54       England
55       Hungary
56       Austria

在每一个匹配中,都会返回NONE。第54场比赛有3支不同的队伍,第55场和第56场比赛只有一个参赛名额,因此没有对手可与之竞争。

第二次反馈

澄清疑问。如果你只看一下德国的简短查询;md1";已经保持了德国队比赛的任何记录。所以第二个连接到";md2";,我只关心同一场比赛,所以我可以参加同一场匹配_no。然而,在";md2";别名,"表示不相等。!=逻辑NOT。所以join是从MD1开始,在同一个比赛id上加入MD2别名。但是,只告诉我球队不相同的地方。所以第一个实例持有德国的团队ID(已经获得资格(,因此给了我第二个团队ID。所以现在我可以使用第二个(md2(实例团队ID加入该国,只为波兰确认。

这能为你澄清事情吗?

最新更新