使用HAVING子句统计SQL查询的结果

使用HAVING子句统计SQL查询的结果,sql,sql-server,count,greatest-n-per-group,Sql,Sql Server,Count,Greatest N Per Group,您是否能够在带有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_issue

您是否能够在带有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
`

在GROUPBY子句中使用COUNT将为每个组提供一个计数。如果您需要组数的计数,它必须是一个单独的查询,就像您的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

您还可以使用子查询

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

假设您有一个表,其中包含名为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'
如果没有应用程序表,您可以从tbl_ui_paymentstubs A中选择不同的列appid,但这将不起作用。与给出的其他查询相比,它仍然是一个竞争者

其他说明:

您不需要执行isnullcolumn,0>0,因为column>0已经排除了null

@ar和@bdukes的查询在内部SELECT子句中不需要任何内容,它们可以是SELECT 1,这可能是一种性能改进,没有其他变化

我希望col_payment_Issuited_date上有一个约束,这样值就不会有时间段,比如上午11:23,否则您的BETWEEN子句最终将无法获取整个月的正确数据

更新

值得一提的是,日期格式“20100901”适用于任何语言或DATEFIRST设置。我鼓励你养成使用它的习惯。其他格式,如“09/01/2010”或“2010/09/01”等,可能会混淆月份和日期。 @德斯科特说:

有一个tbl_应用程序,但在本例中不使用。我可以加入它,但我只是计算这个查询的付款,所以它不是必需的


你介意试试我的查询,并给我反馈它与其他方法相比的性能吗?我希望即使在查询中有额外的连接,它也能表现得很好。

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

SELECT Column1 , count(*) Num
FROM TABLE_NAME whe   
GROUP BY Column1 
HAVING count(*) > 1  
ORDER BY num desc;

你能介绍一下你的桌子结构吗?我不明白您为什么在这个查询中使用min…我必须找到每个索赔AppID的最早付款,如果该付款是该索赔的第一笔付款,并且是当月付款,请将其计算在内。此示例按原样抛出一个错误。我知道你想说什么,但ar有一个有效的解决方案。所以我必须给那个人打分。不过我很感谢你的帮助!固定的显然,如果不命名子查询,就无法从子查询中进行选择。您不能在WHERE中使用子查询。。。在一份名为OK的声明中,我给了你们,正如我在Emtucifor提出日期时间和中间期后注意到的,另一张海报使用的是中间期。虽然这可能适用于较新的日期数据类型,但也需要考虑时间部分。@DScott实际上,他的查询与两者完全相同。他只是明确表示。请参阅我的更新查询,以获取包含当月最后一天所有时间的正确方法。根据MS SQl Server 2008数据库开发,建议使用>=谢谢提供信息。关于中间的问题,你是对的,我没有注意到我选择的原始解决方案。既然另一张海报已经更正了他们的答案,我就选了那张。有一个tbl_应用程序,但在本例中不使用。我可以加入,但我只是在计算这个查询的付款,所以它不是必需的。非常好,彻底的响应,@EmtuciforAt在网站开发的这一点上,没有足够的数据来查看性能。我认为表中最多有100行,其中28行当前保存“有效”数据。