我可以从sql server中的一个sql查询中获取count()和行吗?

时间:2010-05-09 15:22:18

标签: sql sql-server tsql aggregate

我想获得结果的总数和某些查询的前n行 - 是否可能 在一个声明中?

我希望结果如下:

count(..) column1        column2
125         some_value   some_value
125         some_value   some_value

提前谢谢!

4 个答案:

答案 0 :(得分:8)

像这样:

SELECT TOP 100 --optional
    MC.Cnt, M.Column1, M.Column2
FROM
    myTable M
    CROSS JOIN
    (SELECT COUNT(*) AS Cnt FROM myTable) MC

编辑:在downvote和COUNT / OVER回答之后。我的2张桌子的比较

你可以看到我的CROSS JOIN /简单聚合和COUNT /空ORDER BY子句之间的巨大差异

SELECT COUNT(*) OVER() AS C, key1col, key2col
FROM myTable

(24717 row(s) affected)

Table 'Worktable'. Scan count 3, logical reads 49865, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'myTable'. Scan count 1, logical reads 77, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

StmtText
  |--Nested Loops(Inner Join)
       |--Table Spool
       |    |--Segment
       |         |--Index Scan(OBJECT:([MyDB].[dbo].[myTable].[IX_useful]))
       |--Nested Loops(Inner Join, WHERE:((1)))
            |--Compute Scalar(DEFINE:([Expr1003]=CONVERT_IMPLICIT(int,[Expr1005],0)))
            |    |--Stream Aggregate(DEFINE:([Expr1005]=Count(*)))
            |         |--Table Spool
            |--Table Spool

SELECT
    MC.Cnt, M.key1col, M.key2col
FROM
    myTable M
    CROSS JOIN
    (SELECT COUNT(*) AS Cnt FROM myTable) MC

(24717 row(s) affected)

Table 'myTable'. Scan count 2, logical reads 154, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.


StmtText
  |--Nested Loops(Inner Join)
       |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1009],0)))
       |    |--Stream Aggregate(DEFINE:([Expr1009]=Count(*)))
       |         |--Index Scan(OBJECT:([MyDB].[dbo].[myTable].[IX_useful]))
       |--Index Scan(OBJECT:([MyDB].[dbo].[myTable].[IX_useful] AS [M]))

我在570k行的表格上重复了这一点,这里是IO

Table 'Worktable'. Scan count 3, logical reads 1535456, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'myTable'. Scan count 1, logical reads 2929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.


Table 'myTable'. Scan count 34, logical reads 6438, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

答案 1 :(得分:6)

怎么样

SELECT COUNT(*) OVER() AS C, COLUMN1, COLUMN2
FROM TABLE  

关于CROSS JOIN个问题 在繁重的INSERT / DELETE环境中,交叉连接将返回错误的行数。

从多个连接中尝试这个 连接1

set nocount on;
drop table dbo.test_table;
GO
create table dbo.test_table
(
    id_field uniqueidentifier not null default(newid()),
    filler char(2000) not null default('a')
);
GO
create unique clustered index idx_id_fld on dbo.test_table(id_field);
GO
while 1 = 1
insert into dbo.test_table default values;

连接2

select T2.cnt, T1.id_field, T1.filler
from dbo.test_table T1
cross join (select COUNT(*) as cnt from dbo.test_table) T2

select T2.cnt, T1.id_field, T1.filler
from dbo.test_table T1
cross join (select COUNT(*) as cnt from dbo.test_table) T2

select T2.cnt, T1.id_field, T1.filler
from dbo.test_table T1
cross join (select COUNT(*) as cnt from dbo.test_table) T2

每次记录的计数(@@ROWCOUNT)都与T2.cnt

不同

如果是COUNT(*) OVER(),则只有一次表扫描,而@@ROWCOUNT始终与T2.cnt相同

关于查询计划 - SQL 2005 SP3在执行COUNT(*) OVER()时似乎比SQL 2008 R2弱得多。最重要的是,它错误地报告了查询成本(我从未想过子查询可能花费超过整个查询的100%)。

在很多情况下,COUNT(*) OVER()的费用是CROSS JOIN的50-75%

交叉连接的最佳情况是,如果有一个非常窄的索引来进行计数。这样,将对数据进行聚簇索引扫描+对计数进行索引扫描。

与往常一样,最好是衡量,衡量,衡量并采用您乐于接受的折衷方案。

答案 2 :(得分:3)

可以使用CROSS JOIN和CTE执行此操作,但效率不高:

WITH Rows_CTE AS
(
    SELECT Column1, Column2
    FROM Table
    WHERE (...)
)
SELECT c.Cnt, r.Column1, r.Column2
FROM Rows_CTE r
CROSS JOIN (SELECT COUNT(*) AS Cnt FROM Rows_CTE) c

我认为获得所需内容的更好方法是使用单个查询但使用多个结果集,您可以使用COMPUTE执行此操作:

SELECT Column1, Column2
FROM Table
WHERE (...)
COMPUTE COUNT([Column1])

答案 3 :(得分:0)

试试这个查询:

select ColumnId,Descr,(select COUNT(*) from ColumnSetUp)as c
from ColumnSetUp
group by ColumnId,Descr