2010-09-22 95 views
9

您是否可以在具有HAVING子句的查询中使用COUNT,以便COUNT返回行数?当我尝试时,我得到了ID在表格中显示的次数。下面是该查询:SQL查询带有HAVING子句的COUNT结果

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号

,但使用COUNTGROUP BY条款将为每个组的计数

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 

`

+0

请问你可以发表你的餐桌结构吗?我很困惑你为什么在这个查询中使用min ... – armonge 2010-09-22 14:16:22

+0

我必须找到每个索赔(AppID)的最早付款,如果该付款是该索赔的第一个付款,并且当前月份下降,请将其计数。 – 2010-09-22 14:24:41

回答

11

:想知道是否有一个更优雅的方式。如果你想要计算组数,它必须是一个单独的查询(如你的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 
+0

这个例子是,不幸的是抛出一个错误。我知道你在哪里,但'ar'有一个“工作”的解决方案。所以我必须向那个人提供点数。尽管我很欣赏这个帮助! – 2010-09-22 14:28:39

+0

固定。显然你不能从子查询中选择而不命名子查询。 (你不能在'WHERE ... IN'语句中使用子查询_with_名称) – bdukes 2010-09-22 17:36:53

+0

好吧,我给你了,正如我在Emtucifor提出DateTime和BETWEEN问题后注意到的,另一张海报使用了BETWEEN 。虽然这可能适用于较新的DATE数据类型,但时间部分也需要考虑。 – 2010-09-22 18:57:31

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已经排除了空值。

  • @ AR的和@bdukes的查询并不需要内部SELECT子句中的任何东西,他们可以只是SELECT 1,它可能是一个性能改进(没有别的变化)

  • 我希望有一个约束在col_payment_issued_date上,以便值不具有诸如上午11:23的时间部分,否则您的BETWEEN子句最终将无法为整个月提取正确的数据。

更新

  • 对于它的价值,日期格式 '20100901' 将工作无处不在,用任何语言或DATEFIRST设置。我鼓励你养成使用它的习惯。其他格式,例如'09/01/2010'或'2010/09/01'等可以使月份和日期混在一起。

@DScott说:

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

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

+0

感谢您的信息。你对BETWEEN问题是正确的,我没有注意到我选择的原始解决方案。现在另一张海报已经纠正了他们的答案,我选择了一个。有一个tbl_Application,但在这个例子中没有使用。我*可以*加入到它,但我只是计算这个查询的付款,所以它不是必需的。 – 2010-09-22 19:01:07

+0

伟大的,彻底的回应,@Emtucifor – bdukes 2010-09-22 19:20:16

+0

@bdukes谢谢! – ErikE 2010-09-22 21:48:46