har*_*ded 3 sql-server sql-server-2016
我有一个这种结构的表
Create Table Example (
[order] INT,
[typeID] INT
)
Run Code Online (Sandbox Code Playgroud)
有了这些数据:
order|type
1 7
2 11
3 11
4 18
5 5
6 19
7 5
8 5
9 3
10 11
11 11
12 3
Run Code Online (Sandbox Code Playgroud)
我需要根据订单获取每种类型的计数,例如:
type|count
7 1
11 **2**
18 1
5 1
19 1
5 **2**
3 1
11 **2**
3 1
Run Code Online (Sandbox Code Playgroud)
上下文
让我们说这张桌子是关于房子的,所以我在订单中有一个清单.所以我有
所以我需要显示信息浓缩.我需要说:
因此,计数基于订单.该DENSE_RANK函数将帮助我,如果我能够在RANK重新分区更改时.
所以我有一个答案,但我必须警告你,由于它是如何完成的,它可能会引起一些焦虑.它使用了一种称为" 古怪的更新 "的东西.如果你计划实现这一点,请通过链接文章阅读上帝的爱,并了解这是一个"无证件的黑客",需要精确实施,以避免意外的后果.
如果你有一点点数据,我只是为了简单和清晰而痛苦地排着行.但是,如果您有大量数据并且仍需要高性能,则可能会这样做.
要求
它能做什么
你知道人们怎么告诉你表中的数据没有隐含的顺序吗?这仍然是99%的时间.除了我们知道最终它必须以某种顺序存储在磁盘上.这就是我们在这里利用的顺序.通过强制进行聚簇索引更新以及可以在更新列的同一更新语句中分配变量这一事实,您可以快速有效地滚动数据.
我们设置数据:
if object_id('tempdb.dbo.#t') is not null drop table #t
create table #t
(
_order int primary key clustered,
_type int,
_grp int
)
insert into #t (_order, _type)
select 1,7
union all select 2,11
union all select 3,11
union all select 4,18
union all select 5,5
union all select 6,19
union all select 7,5
union all select 8,5
union all select 9,3
union all select 10,11
union all select 11,11
union all select 12,3
Run Code Online (Sandbox Code Playgroud)
这是更新声明.我将介绍下面的每个组件
declare @Order int, @Type int, @Grp int
update #t with (tablockx)
set @Order = _order,
@Grp = case when _order = 1 then 1
when _type != @Type then @grp + 1
else @Grp
end,
@Type = _type,
_grp = @Grp
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)
(tablockx).如果你正在使用临时表,你知道桌面上没有争用,但仍然是一个很好的习惯(如果使用这种方法甚至可以被认为是一个很好的习惯).@Order = _order.这看起来像一个毫无意义的陈述,它有点像.但是,由于它_order是表的主键,因此将其分配给变量是强制SQL执行聚簇索引更新的原因,这对于此工作至关重要_order为1(第一行)时,只需将@Grp变量设置为1.如果在任何给定行上,列值_type与变量值不同@type,则增加分组变量.如果值相同,我们只需坚持@Grp上一行中的值.@Type使用列_type的值更新变量.注意这个HAS在分配之后@Grp才能获得正确的值._grp = @Grp.这是使用步骤3的结果更新实际列值的位置.option (maxdop 1).这意味着最大并行度设置为1.换句话说,SQL不能执行任何可能导致排序关闭的任务并行化.现在只是在_grp现场分组的问题._grp每个连续批次都有一个唯一的值_type.
结论
如果这看起来香蕉和hacky,它是.就像所有事情一样,你需要花一点时间,如果你计划实施它,我建议你真正使用这个概念来完全理解它,因为我保证没有其他人会知道如何解决它如果你在半夜接到一个电话,它就会破裂.
| 归档时间: |
|
| 查看次数: |
75 次 |
| 最近记录: |