COUNT个具有HAVING子句的SQL查询的结果

问题描述 投票:10回答:4

您是否可以在带有HAVING子句的查询中使用COUNT,以便COUNT返回行数?当我尝试时,我会得到ID在表中显示的次数计数。这是查询:

SELECT col_appid, min(col_payment_issued_date) as PayDate  
FROM tbl_ui_paymentstubs  
WHERE isnull(col_payment_amount,0) > 0  
GROUP BY col_appid  
HAVING min(col_payment_issued_date) >= '09/01/2010' and min(col_payment_issued_date) <= '09/30/2010'

我返回6行,这很好,但是我想只返回数字6。

我发现我可以这样做,但是想知道是否还有另一种更优雅的方式:

WITH Claims_CTE(AppID, PayDate) as
(  
 SELECT col_appid, min(col_payment_issued_date) as PayDate
 FROM tbl_ui_paymentstubs
 WHERE isnull(col_payment_amount,0) > 0
 GROUP BY col_appid
 HAVING min(col_payment_issued_date) >= '09/01/2010' and min(col_payment_issued_date) <= '09/30/2010'
)  
 SELECT count(AppID) as Amount from Claims_CTE

`

sql sql-server count greatest-n-per-group
4个回答
11
投票

COUNTGROUP BY子句一起使用将为每个组提供计数。如果要计算组数,则必须是一个单独的查询(如您的CTE示例)。

我只使用一个简单的子查询,而不是CTE:

SELECT COUNT(*) FROM 
 (SELECT col_appid, min(col_payment_issued_date) as PayDate  
  FROM tbl_ui_paymentstubs  
  WHERE isnull(col_payment_amount,0) > 0  
  GROUP BY col_appid  
  HAVING
     min(col_payment_issued_date) >= '09/01/2010'
     and min(col_payment_issued_date) <= '09/30/2010') Claims

4
投票

您也可以使用子查询。

SELECT count(*) as Amount
FROM (
    SELECT col_appid FROM tbl_ui_paymentstubs
    WHERE isnull(col_payment_amount,0) > 0
    GROUP BY col_appid
    HAVING min(col_payment_issued_date) BETWEEN '09/01/2010' AND '09/30/2010'
) Claims

2
投票

假设您有一个表,其中包含名为App的col_appid值的不同列表,该查询也可以使用,并且可能会获得更好的性能:

SELECT Count(*)
FROM
   App A
   CROSS APPLY (
      SELECT TOP 1 col_payment_issued_date
      FROM tbl_ui_paymentstubs P
      WHERE
         P.col_payment_amount > 0
         AND A.col_appid = P.col_appid
      ORDER BY col_payment_issued_date
   ) X
WHERE
   X.col_payment_issued_date >= '09/01/2010'
   AND X.col_payment_issued_date < '10/01/2010'

如果没有App表,您可以替换(SELECT DISTINCT col_appid FROM tbl_ui_paymentstubs) A,但效果不佳。与给出的其他查询相比,它可能仍然是竞争者。

[其他说明:

  • 您不需要执行isnull(column, 0) > 0,因为column > 0已经排除了NULL。

  • @ ar和@bdukes查询在内部SELECT子句中不需要任何内容​​,它们可以只是SELECT 1,这可能会提高性能(没有其他变化)

  • 我希望对col_payment_issued_date有所限制,以使值不具有诸如11:23 AM这样的时间部分,否则您的BETWEEN子句最终将不会提取整个月的正确数据。

更新

  • 关于它的价值,日期格式'20100901'将在任何语言,DATEFIRST设置下随处可用。我鼓励您养成使用它的习惯。其他格式,例如'09 / 01/2010'或'2010/09/01'等可以使月份和日期混淆。

@@ DScott说:

有一个tbl_Application,但在这种情况下不使用。我可以加入,但我只是在为此查询计算付款,因此不是必需的。

您介意尝试我的查询并与其他方法相比向我提供有关其性能的反馈吗?我希望即使在查询中有额外的联接,它的性能也很好。


0
投票

在查询中使用下面的查询来计算Oracle中的重复记录。

SELECT Column1 , count(*) Num
FROM TABLE_NAME whe   
GROUP BY Column1 
HAVING count(*) > 1  
ORDER BY num desc;
© www.soinside.com 2019 - 2024. All rights reserved.