多个SQL计数与多个条件的结合

5

我一直在尝试优化从数据库检索数据以在软件开发的“仪表板”页面上显示的方式。

我的数据库结构如下:

  • 需求表包含各种需求及其各个字段,但重要的是REQ_ID作为键。
  • 任务表包含多个任务,其中包括TASK_ID、TASK_NAME(DEV、TEST或RELEASE)、TASK_STATUS(未开始、完成、受阻)、TASK_WINDOW(完成任务的周数等),并且与一个包含REQ_I的需求相关联。例如,一个需求可能有多个开发任务、测试任务和发布任务,但只有当与需求相关的所有开发任务都完成时,才能算作开发完成;否则就是不完整的。

我想查询这两个表,以便在单个查询中提供一个结果集,该结果集分别包含每个DEV任务窗口中DEV Complete、Test Complete和Release Complete需求的数量。目前,我正在执行多个查询,每个查询都包含子查询,然后使用PHP汇总结果,但总共需要15秒才能执行。请问有谁可以帮助我将其合并为一个单独的查询呢?

2个回答

11
SELECT r.REQ_ID, 
       SUM(CASE WHEN t.TASK_NAME = 'DEV' THEN 1 ELSE 0 END) AS DevComplete,
       SUM(CASE WHEN t.TASK_NAME = 'TEST' THEN 1 ELSE 0 END) AS TestComplete,
       SUM(CASE WHEN t.TASK_NAME = 'RELEASE' THEN 1 ELSE 0 END) AS ReleaseComplete
    FROM Requirements r
        INNER JOIN Tasks t
            ON r.REQ_ID = t.REQ_ID
    WHERE t.TASK_STATUS = 'Complete'
    GROUP BY r.REQ_ID

1
+1 - 好老的 SUM(CASE...)。有什么它不能解决的问题吗? - JNK
你应该能够消除连接操作,只需对t.REQ_ID进行分组。 - gcooney
@JNK:确实。我在上周末参加了SQL Saturday 67活动,Kevin Boles进行了一场关于高级TSQL解决方案的演讲,并表示"CASE"是他在SQL中最喜欢的四个字母。我必须同意他的看法。 - Joe Stefanelli
@gcooney:我想让查询保持开放状态,以便可能需要来自“需求”表的其他列。 - Joe Stefanelli
@Joe Stefanelli 好的。如果需要其他列,则连接肯定是必要的。如果不需要,删除连接可能是一种优化。 - gcooney
显示剩余3条评论

0

我知道这是一个老问题,但我用以下模式进行了测试:

模式1:

SELECT
 [Count1] = SUM(CASE WHEN ... THEN 1 ELSE 0 END),
 [Count2] = SUM(CASE WHEN ... THEN 1 ELSE 0 END)
FROM
 [Table]
GROUP BY
 [Field]

模式 2:

SELECT
  [COUNT1] = (SELECT COUNT(*) FROM [Table] WHERE ...),
  [Count2] = (SELECT COUNT(*) FROM [Table] WHERE ...)

在我的情况下,运行这两个查询时,模式2占用了36%的时间,而模式1占用了64%的时间。对我来说,模式1看起来更优雅,但在我的场景中表现不佳。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接