【问题标题】:Beginner SQL: How can I combine these SQL queries to return two sum columns side-by-side?初学者 SQL:如何组合这些 SQL 查询以并排返回两个总和列?
【发布时间】:2022-01-12 18:47:46
【问题描述】:

我目前有两个小查询,我正在尝试将它们结合起来。首先给我一份工作的总预算时间。第二个给了我实际小时数。

当我尝试合并这些时,我使用了两个左连接,结果预算时间过多。我的 group-by 或 join 逻辑出了点问题,但我不确定是哪一个。

--Query for Budget Hours 
SELECT  bdglin.recnum, --this is jobnum
        actrec.jobnme, 
        SUM(hrsbdg) AS budgethours
FROM    bdglin
LEFT JOIN actrec ON actrec.recnum = bdglin.recnum
WHERE actrec.jobtyp = 2 
GROUP BY bdglin.recnum, actrec.jobnme
ORDER BY recnum


--Query for Actual hours 
SELECT  jobcst.jobnum,
        actrec.jobnme,
        SUM(jobcst.csthrs) AS actualhours
FROM    jobcst
LEFT JOIN actrec ON actrec.recnum = jobcst.jobnum
WHERE actrec.jobtyp = 2
GROUP BY jobnum, actrec.jobnme
ORDER BY jobnum

 --Failed attempt to combine them, returns like 50,000 hours for a job
SELECT  bdglin.recnum, 
        actrec.jobnme, 
        SUM(bdglin.hrsbdg) AS BudgetHours, 
        SUM(jobcst.csthrs) AS ActualHrs 
FROM    bdglin 
LEFT JOIN actrec ON actrec.recnum = bdglin.recnum
LEFT JOIN jobcst ON jobcst.jobnum = bdglin.recnum
WHERE actrec.jobtyp = 2 
GROUP BY bdglin.recnum, actrec.jobnme
ORDER BY jobnme

【问题讨论】:

  • 最简单的方法是将每个查询用作derived table,然后将它们连接在一起。
  • 第一个查询实际上不是左连接,因为您在 where 中使用列...
  • GROUP BY 每个表在一个单独的派生表中。然后加入。

标签: sql sql-server join group-by


【解决方案1】:

最简单的方法是将两个工作查询滚动到 CTE 中,然后加入 CTE。这是你应该学习的技术(尽管它并不总是最好的方法,所以不要盲目地应用这个或任何其他模式)。

with budgethrs as ( 
   SELECT  bdglin.recnum as jobnum, actrec.jobnme, 
        SUM(hrsbdg) AS budgethours
    FROM bdglin 
    JOIN actrec ON actrec.recnum = bdglin.recnum
    WHERE actrec.jobtyp = 2 
    GROUP BY bdglin.recnum, actrec.jobnme
), 
actualhrs as (
   SELECT  jobcst.jobnum, actrec.jobnme,
        SUM(jobcst.csthrs) AS actualhours
   FROM jobcst
   JOIN actrec ON actrec.recnum = jobcst.jobnum
   WHERE actrec.jobtyp = 2
   GROUP BY jobnum, actrec.jobnme
)
select isnull(jobcst.jobnum, actualhrsjobnum) as jobnum, 
       ...
from budgethrs full outer join actualhrs
  on budgethrs.jobnum = actualhrs.jobnum 
 and budgethrs.jobnme = actualhrs.jobnme 
order by ...
;

注意完整的外部连接。我留给你去发现和验证的东西是有原因的。由于完全连接,您需要使用 CASE 表达式来“挑选获胜者”以正确处理不匹配的行。为了更充分地理解这​​一点,只需将所有列(临时)包含在选择列表中,并使用良好的样本数据集进行测试。您需要在测试数据中同时包含预算和实际数字、只有预算数字和实际数字的工作编号。

还请注意,我将您的外部联接更改为内部联接。如前所述,在 WHERE 子句中引用未保留的表(例如,actrec)在逻辑上将它们转换为内部连接。我们不要试图欺骗任何读者。

我可以看到一种更有效的方法来编写查询,但这是实现目标的快速而肮脏的方法。

【讨论】:

  • 谢谢,最终解决了,但不知道如何在此处添加完成的代码。可能仍然效率低下,但是哦,你关于效率的观点很有帮助!花一些时间学习子选择,这些让生活变得更轻松
猜你喜欢
  • 2019-02-16
  • 2020-07-08
  • 2014-07-09
  • 2015-06-29
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
相关资源
最近更新 更多