【问题标题】:Two queries work independently but can not conjoin them两个查询独立工作但不能合并它们
【发布时间】:2021-04-01 15:19:28
【问题描述】:

我有两个独立工作的查询,但组合时会抛出不正确的结果;

查询 1:

SELECT 
    ID, 
    (FirstName || " " || Surname) AS Player, 
    COUNT (PlayerMatch.PlayerID) AS 'Matches', 
    SUM (PlayerMatch.MinuteOff - PlayerMatch.MinuteOn) AS 'Mins',
    SUM (PlayerMatch.Shots) AS 'Shots',
    SUM (PlayerMatch.ShotOnTarget) AS 'On Target',
    ROUND (1.0 * SUM (PlayerMatch.ShotOnTarget) / SUM (PlayerMatch.Shots), 2) AS 'Shots on target'
FROM 
    Players
LEFT JOIN 
    PlayerMatch ON PlayerMatch.PlayerID = Players.ID 
GROUP BY  
    Players.ID
HAVING 
    COUNT (PlayerMatch.PlayerID) > 0;

和查询 #2:

SELECT 
    ID, 
    (FirstName || " " || Surname) AS Player,
    COUNT (Goals.ScorerID) AS 'Goals',
FROM 
    Players
LEFT JOIN 
    Goals ON Goals.ScorerID = Players.ID 
GROUP BY  
    Players.ID
HAVING 
    COUNT (Goals.ScorerID) > 0
ORDER BY  
    COUNT (Goals.ScorerID) DESC;

当这样组合时:

SELECT 
    ID, 
    (FirstName || " " || Surname) AS Player, 
    COUNT (PlayerMatch.PlayerID) AS 'Matches', 
    SUM (PlayerMatch.MinuteOff - PlayerMatch.MinuteOn) AS 'Mins',
    SUM (PlayerMatch.Shots) AS 'Shots',
    SUM (PlayerMatch.ShotOnTarget) AS 'On Target',
    COUNT (Goals.ScorerID) AS 'Goals',
    ROUND (1.0 * SUM (PlayerMatch.ShotOnTarget) / SUM (PlayerMatch.Shots), 2) AS 'Shots on target'
FROM 
    Players
LEFT JOIN 
    PlayerMatch ON PlayerMatch.PlayerID = Players.ID 
LEFT JOIN 
    Goals ON Goals.ScorerID = Players.ID 
GROUP BY  
    Players.ID
HAVING 
    COUNT (PlayerMatch.PlayerID) > 0 
    AND COUNT (Goals.ScorerID) > 0
ORDER BY  
    COUNT (Goals.ScorerID) DESC;

专栏

    COUNT (Goals.ScorerID) AS 'Goals',

返回正确数量的结果,但返回错误的详细信息。

非常感谢任何帮助。

【问题讨论】:

  • 请用您正在运行的数据库标记您的问题:mysql、oracle、postgres...?

标签: sql sqlite count sum left-join


【解决方案1】:

对于给定的玩家,您在两个表中都有多个匹配的记录,因此连接乘以行,并且聚合的结果是关闭的。您需要在子查询中预先聚合:

select p.id, p.firstname || ' ' || p.surname as player,
    g.goals,
    pm.matches, pm.mins, pm.shots, pm.on_target, pm.on_target_ratio
from players p
left join (select scorerid, count(*) as goals from goals group by scorerid) g
    on g.scorerid = p.id
left join (
    select playerid,
        count(*) as matches, 
        sum (minuteoff - minuteon) as mins
        sum(shots) as shots,
        sum(shotontarget) as on_target,
        round(1.0 * sum(shotontarget) / sum(shots), 2) as on_target_ratio
    from playermatch
    group by playerid
) pm on pm.Player_id = p.id

根据您使用的数据库,可能会有更好的选择,尤其是在它支持横向连接的情况下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多