【问题标题】:Consolidating a COUNT query合并 COUNT 查询
【发布时间】:2010-12-17 06:24:09
【问题描述】:

我有一个页面,我在其中运行初始 SQL 查询以获取主题列表,然后循环此查询并为从原始主题查询返回的每条记录运行两个额外的查询(我恰好在ColdFusion,但不确定这真的很重要)。这两个额外的查询对该特定主题进行 COUNT 运算,然后输出结果(打印主题名称,然后是该主题的两个计数)。我正在尝试提高此页面的性能,并想知道是否可以以某种方式将其组合到一个查询中。

初始查询:

选择主题 ID,主题名称 来自主题 按主题名称订购

初始查询循环内的查询:

选择 COUNT(test_ID) 作为 priority_count FROM 测试队列 WHERE priority_flag = 1 AND subject_ID = #SubjectQuery.subject_ID# 选择 COUNT(test_ID) 作为locked_count FROM 测试队列 WHERE 锁定 = 1 AND subject_ID = #SubjectQuery.subject_ID#

关于如何优化这些的建议? DB 是 MS SQL 2008。谢谢。

【问题讨论】:

  • 你如何根据subject_ID过滤Test_Queue,这里没有显示。
  • 在循环中的查询中,WHERE 子句是否包含 subject_ID?
  • 对不起,我删除了一些无关的信息,不小心把它拿出来了。我已经编辑了上面的查询。
  • 提高性能的第一种方法是摆脱循环(如前所述)。其次,将子查询的性能与 CASE 选项进行比较。 (有些数据库使用 CASE 可能会做得更好。)但是 MS SQL 也可能会表现得很好。

标签: sql sql-server coldfusion count


【解决方案1】:
SELECT 
    subject_ID, 
    subject_name,
    priority_count = (select count(test_id) from test_queue where priority_flag = 1),
    locked_count = (select count(test_id) from test_queue where locked = 1)
FROM Subjects
ORDER BY subject_name

或者,如果计数应该包含 subject_id(只是猜测),那么

SELECT 
    s.subject_ID, 
    s.subject_name,
    priority_count = (select count(test_id) from test_queue t where priority_flag = 1 and t.subject_id = s.subject_id),
    locked_count = (select count(test_id) from test_queue t where locked = 1 and t.subject_id = s.subject_id)
FROM Subjects s
ORDER BY subject_name

【讨论】:

  • +1 这是我在选择中使用子查询的路线。我不得不说我使用格式 () AS output_var。只是我的喜好,不应该有任何区别。
【解决方案2】:

应该这样做,假设从subjects到test_queue的连接列是正确的,你没有指定test_queue中的哪一列引用了subjects

select
    subjects.subject_id
   ,subjects.subject_name
   ,sum(case when test_queue.priority_flag=1 THEN 1 ELSE 0 END) as priority_count
   ,sum(case when test_queue.locked=1 THEN 1 ELSE 0 END) as locked_count
  from
    subjects
    left join test_queue
       on subjects.subject_id=test_queue.subject_id
  group by subjects.subject_id, subjects.subject_name
  order by subjects.subject_name

【讨论】:

  • 我喜欢您使用 group by vs distinct...顺便说一句,为什么每个人都以不同的样式/格式编写 sql 代码?只是好奇:)
【解决方案3】:

像这样? (如果priority_flag 或locked 是SUM 不喜欢的类型,您可能需要转换为INT)

SELECT
  subject_ID
, subject_name
, SUM(priority_flag) AS priority_count
, SUM(locked) AS locked_count
FROM Subjects s, Test_Queue tq
GROUP BY subject_ID, subject_name
ORDER BY subject_name
;

【讨论】:

    【解决方案4】:

    我会赌一下 Test_Queue.Subject_ID = Subjects.Subject_ID

    SELECT s.subject_ID, s.subject_name, COUNT(t1.*) as priority_count, COUNT(t2.*) as locked_count
      FROM Subjects s
      LEFT OUTER JOIN Test_Queue t1
        ON s.Subject_ID = t1.Subject_ID
       AND t1.priority_flag = 1
      LEFT OUTER JOIN Test_Queue t2
        ON s.Subject_ID = t2.Subject_ID
       AND t2.locked = 1
     GROUP by s.subject_ID, s.subject_name
     ORDER BY s.subject_name
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 2019-05-16
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      相关资源
      最近更新 更多