Gre*_*reg 6 sql t-sql sql-server aggregate
我想获得结果的总数和一些查询的前n行 - 是否可以在一个语句中?
我希望结果如下:
count(..) column1 column2
125 some_value some_value
125 some_value some_value
Run Code Online (Sandbox Code Playgroud)
先感谢您!
像这样:
SELECT TOP 100 --optional
MC.Cnt, M.Column1, M.Column2
FROM
myTable M
CROSS JOIN
(SELECT COUNT(*) AS Cnt FROM myTable) MC
Run Code Online (Sandbox Code Playgroud)
编辑:在downvote和COUNT/OVER回答之后.对我的两张桌子的比较
您可以看到我的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]))
Run Code Online (Sandbox Code Playgroud)
我在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.
Run Code Online (Sandbox Code Playgroud)
关于什么
SELECT COUNT(*) OVER() AS C, COLUMN1, COLUMN2
FROM TABLE
Run Code Online (Sandbox Code Playgroud)
关于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;
Run Code Online (Sandbox Code Playgroud)
连接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
Run Code Online (Sandbox Code Playgroud)
每次,记录(@@ROWCOUNT
)的计数都不同T2.cnt
在这种情况下COUNT(*) OVER()
,只有一个表扫描,并@@ROWCOUNT
始终相同T2.cnt
关于查询计划 - SQL 2005 SP3似乎COUNT(*) OVER()
比SQL 2008 R2 弱得多.最重要的是,它错误地报告了查询成本(我从未想过子查询可能花费超过整个查询的100%).
在很多场景中,成本COUNT(*) OVER()
在50-75%之间CROSS JOIN
交叉连接的最佳情况是,如果有一个非常窄的索引来进行计数.这样,将对数据进行聚簇索引扫描+对计数进行索引扫描.
与往常一样,最好是衡量,衡量,衡量并采用您乐于接受的妥协方案.
您可以使用 aCROSS 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
Run Code Online (Sandbox Code Playgroud)
我认为获得您想要的结果的更好方法是使用单个查询但多个结果集,您可以通过使用以下方法来实现COMPUTE
:
SELECT Column1, Column2
FROM Table
WHERE (...)
COMPUTE COUNT([Column1])
Run Code Online (Sandbox Code Playgroud)