SQL Server: How can I use the COUNT clause without GROUPing?

爷,独闯天下 提交于 2019-12-19 10:59:28

问题


I'm looking get two things from a query, given a set of contraints:

  • The first match
  • The total number of matches

I can get the first match by:

SELECT TOP 1
    ID,
    ReportYear,
    Name,
    SignDate,
     ... 
FROM Table
WHERE
     ...
ORDER BY ... //I can put in here which one I want to take

And then I can get the match count if I use

SELECT
    MIN(ID),
    MIN(ReportYear),
    MIN(Name),
    MIN(SignDate),
     ... ,
    COUNT(*) as MatchCount
FROM Table
WHERE
     ...
GROUP BY
     ??? // I don't really want any grouping

I really want to avoid both grouping and using an aggregate function on all my results. This question SQL Server Select COUNT without using aggregate function or group by suggests the answer would be

SELECT TOP 1
    ID,
    ReportYear,
    Name,
    SignDate,
     ... ,
    @@ROWCOUNT as MatchCount
FROM Table

This works without the TOP 1, but when it's in there, @@ROWCOUNT = number of rows returned, which is 1. How can I get essentially the output of COUNT(*) (whatever's left after the where clause) without any grouping or need to aggregate all the columns?

What I don't want to do is repeat each of these twice, once for the first row and then again for the @@ROWCOUNT. I'm not finding a way I can properly use GROUP BY, because I strictly want the number of items that match my criteria, and I want columns that if I GROUPed them would throw this number off - unless I'm misunderstanding GROUP BY.


回答1:


Assuming you are using a newish version of SQL Server (2008+ from memory) then you can use analytic functions.

Simplifying things somewhat, they are a way of way of doing an aggregate over a set of data instead of a group - an extension on basic aggregates.

Instead of this:

SELECT
     ... , 
    COUNT(*) as MatchCount
FROM Table
WHERE
     ...

You do this:

SELECT
     ... ,
    COUNT(*) as MatchCount OVER (PARTITION BY <group fields> ORDER BY <order fields> )
FROM Table
WHERE
     ...
GROUP BY

Without actually running some code, I can't recall exactly which aggregates that you can't use in this fashion. Count is fine though.




回答2:


Well, you can use OVER clause, which is an window function.

SELECT  TOP (1)
    OrderID, CustID, EmpID,
    COUNT(*) OVER() AS MatchCount
FROM    Sales.Orders
WHERE   OrderID % 2 = 1
ORDER BY OrderID DESC 



回答3:


Try next query:

select top 1
    *, count(*) over () rowsCount
from
    (
        select
            *, dense_rank() over (order by ValueForOrder) n
        from
            myTable
    ) t
where
    n = 1


来源:https://stackoverflow.com/questions/10444333/sql-server-how-can-i-use-the-count-clause-without-grouping

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!