gpt4 book ai didi

sql - 将任意 SQL SELECT TOP(x) 转换为 SELECT COUNT(*)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:36:46 25 4
gpt4 key购买 nike

我希望能够采用通常会返回大量行(没有 X 限制)的任意 SELECT TOP(X) 查询,并将该查询转换为计算如何返回的查询如果没有 TOP(X)(即 SELECT COUNT(*)),许多行将被返回。请记住,我问的是具有任意数量的连接、where 子句、group by 等的任意查询。

有办法吗?


编辑以显示香农解决方案的语法:

`SELECT TOP(X) [colnames] FROM [tables with joins] 
WHERE [constraints] GROUP BY [cols] ORDER BY [cols]`

成为

`SELECT COUNT(*) FROM 
(SELECT [colnames] FROM [tables with joins]
WHERE [constraints] GROUP BY [cols]) t`

最佳答案

内联 View :

select count(*)
from (...slightly transformed query...) t

...稍微转换的查询...是:

  1. 如果 select 子句包含任何没有名称的列,例如 select ... avg(x) ... 然后执行 1) 列的别名之一,例如avg(x) as AvgX, 2) 删除列,但要确保至少留下一列,或者我最喜欢的 3) 只需让select子句select 1 as C
  2. select 子句中删除 TOP
  3. 删除 order by 子句。

编辑 1 通过为内联 View 添加别名并处理 select 子句中的未命名列来修复。

EDIT 2 但是性能呢?这不需要数据库运行我一开始就想用 TOP(X) 避免的大查询吗?

不一定。对于某些查询,此计数可能会比 TOP(x) 做更多的工作。对于特定查询,可能是这样的情况,您可以通过进行额外更改以删除最终计数不需要的工作来加快等效计数。但是这些简化不能包含在一般方法中采用通常会返回大量行(没有 X 限制)的任意 SELECT TOP(X) 查询并将该查询转换为计算有多少行的查询如果没有 TOP(X),将返回行。

在某些情况下,查询优化器可能会优化一些东西,这样数据库就不会运行大型查询。

例如测试表和数据,使用SQL Server 2005:

create table t (PK int identity(1, 1) primary key,
u int not null unique,
string VARCHAR(2000))

insert into t (u, string)
select top 100000 row_number() over (order by s1.id) , replace(space(2000), ' ', 'x')
from sysobjects s1,
sysobjects s2,
sysobjects s3,
sysobjects s4,
sysobjects s5,
sysobjects s6,
sysobjects s7

u 列上的非聚集索引将比 PK 列上的聚集索引小得多。

然后设置 SMSS 以显示实际执行计划:

select PK, U, String from t
select count(*) from t

第一个 select 进行聚簇索引扫描,因为它需要从叶子中返回数据。第二个查询对为 U 上的唯一约束创建的较小的非聚集索引进行索引扫描。

应用我们得到的第一个查询的转换:

select count(*)
from (select PK, U, String from t) t

运行它并查看计划,再次使用 U 上的索引,与 select count(*) from t 完全相同的计划。不会访问叶子来查找每一行的 String 值。

关于sql - 将任意 SQL SELECT TOP(x) 转换为 SELECT COUNT(*)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1247047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com