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

发布于 2024-08-31 16:32:50 字数 204 浏览 2 评论 0原文

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

我期望的结果是:

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

提前谢谢您!

I'd like to get the total count of results and top n rows of some query - is it possible
in one statement?

I'd expect the results as:

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

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一百个冬季 2024-09-07 16:32:50

像这样:

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

编辑:在投反对票和计数/结束答案后。对我的 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.

Like this:

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

Edit: After downvote and COUNT/OVER answer. A comparison on 2 tables of mine

You can see a huge difference between my CROSS JOIN/simple aggregate and a COUNT/empty ORDER BY clause

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]))

I've repeated this on a table with 570k rows and here is the 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.
中性美 2024-09-07 16:32:50

怎么样

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% 之间。

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

与往常一样,最好是衡量、衡量、衡量并做出您愿意接受的妥协。

what about

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

Regarding CROSS JOIN queries
In a heavy INSERT/DELETE environment, the cross join will return incorrect row count.

Try this from multiple connections
connection 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;

connection 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

Each time, the count of records (@@ROWCOUNT) is different to T2.cnt

In the case of COUNT(*) OVER(), there is only a single table scan and the @@ROWCOUNT is always the same as T2.cnt

Regarding query plans - SQL 2005 SP3 appears to be much weaker at doing COUNT(*) OVER() than SQL 2008 R2. On top of that, it incorrectly reports query costs (I never thought a sub query could cost more than 100% of the entire query).

In a lot of scenarios, the cost of the COUNT(*) OVER() is between 50-75% of the CROSS JOIN

The best case scenario for a cross join would be if there was a very narrow index to do the count on. That way there will be a clustered index scan for the data + an index scan for the count.

As always, it's best to measure, measure, measure and go with the compromise that you're happy to live with.

小清晰的声音 2024-09-07 16:32:50

可以使用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])

You can do this with a CROSS JOIN and CTE, but it's not very efficient:

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

I think a better way to get what you want would be to use a single query but multiple result sets, which you can do by using COMPUTE:

SELECT Column1, Column2
FROM Table
WHERE (...)
COMPUTE COUNT([Column1])
秋风の叶未落 2024-09-07 16:32:50

尝试一下这个查询:

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

give a try for this query:

select ColumnId,Descr,(select COUNT(*) from ColumnSetUp)as c
from ColumnSetUp
group by ColumnId,Descr
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文