我有一个特殊的情况,我得到一些类似于以下内容的行,这来自于我无法控制的某些集成操作。
请使用此脚本进行复制
CREATE TABLE #SOMETABLE
(
FIELD VARCHAR,
VALUE INT
)
INSERT INTO #SOMETABLE
(FIELD,VALUE)
VALUES
('A',1),
('B',3),
('C',5),
('A',90),
('B',15),
('C',21),
('A',31),
('B',75),
('C',82)
SELECT * FROM #SOMETABLE
您会得到
如您所见,A-B-C模式会重复其自身,并保证按此顺序重复,因此我需要使用额外的计算列(GROUP)来标识这些行的“组”。
所以它必须像这样结束
[我尝试过几次la脚的尝试,搜索过google,在这里和那里阅读文章,但我什至不知道Google搜索要使用什么术语,it does seem that SQL Server can identify patterns in rows,但我不确定从哪里开始
所以我的问题是:如何在SQL Server 2014中标识行组?
编辑
很难详细说明,但我可以说这里有一个唯一的ID字段,并且有一个“位置”字段可以保证所有ABC的顺序
CREATE TABLE #SOMETABLE
(
ID INT IDENTITY(1,1) PRIMARY KEY,
FK_FIELD_NAME VARCHAR,
[VALUE] INT,
[FK_FIELD_POSITION] INT
)
INSERT INTO #SOMETABLE
(ID,FK_FIELD_NAME,[VALUE],[FK_FIELD_POSITION])
VALUES
(1,'A',1,17),
(2,'B',3,18),
(3,'C',5,19),
(4,'A',90,17),
(5,'B',15,18),
(6,'C',21,19),
(7,'A',31,17),
(8,'B',75,18),
(9,'C',82,19)
SELECT * FROM #SOMETABLE
尝试一下:
在添加到临时表之前,向该表和VOILA添加一个自动增量:
DROP TABLE #SOMETABLE
CREATE TABLE #SOMETABLE
(
ID int NOT NULL IDENTITY(1,1),
FIELD VARCHAR,
VALUE INT
)
INSERT INTO #SOMETABLE
( FIELD,VALUE)
VALUES
('A',1),
('B',3),
('C',5),
('A',90),
('B',15),
('C',21),
('A',31),
('B',75),
('C',82)
SELECT *, ceiling(ID/3.0) FROM #SOMETABLE
可能是最简单,最简单的方法是使用游标在行上进行迭代:
create table #sometable2
(
field varchar,
[value] int,
[group] int
)
declare @field char(1)
declare @value int
declare @group int = 1
declare something_cursor cursor for
select field, [value] from #sometable
open something_cursor
fetch next from something_cursor into @field, @value
while @@fetch_status = 0
begin
insert into #sometable2 select @field, @value, @group
if @field = 'C' set @group = (select @group + 1)
fetch next from something_cursor into @field, @value
end
close something_cursor
deallocate something_cursor
select * from #sometable2
结果:
╔═══════╤═══════╤═══════╗
║ field │ value │ group ║
╠═══════╪═══════╪═══════╣
║ A │ 1 │ 1 ║
╟───────┼───────┼───────╢
║ B │ 3 │ 1 ║
╟───────┼───────┼───────╢
║ C │ 5 │ 1 ║
╟───────┼───────┼───────╢
║ A │ 90 │ 2 ║
╟───────┼───────┼───────╢
║ B │ 15 │ 2 ║
╟───────┼───────┼───────╢
║ C │ 21 │ 2 ║
╟───────┼───────┼───────╢
║ A │ 31 │ 3 ║
╟───────┼───────┼───────╢
║ B │ 75 │ 3 ║
╟───────┼───────┼───────╢
║ C │ 82 │ 3 ║
╚═══════╧═══════╧═══════╝
您是否可以添加另一个ID列?也许还有ROW_NUMBER()窗口函数。
CREATE TABLE #SOMETABLE
(
ID INT,
FIELD VARCHAR,
VALUE INT
)
INSERT INTO #SOMETABLE
(ID,FIELD,VALUE)
VALUES
(1,'A',1),
(2,'B',3),
(3,'C',5),
(4,'A',90),
(5,'B',15),
(6,'C',21),
(7,'A',31),
(8,'B',75),
(9,'C',82)
SELECT t.*
, ROW_NUMBER() OVER(PARTITION BY t.ID % 3 ORDER BY t.ID) rn
FROM #SOMETABLE t
ORDER BY t.ID
或者如果您无法添加ID字段...我不保证:
SELECT t2.*
, ROW_NUMBER() OVER(PARTITION BY t2.ID % 3 ORDER BY t2.ID) rn
FROM(
SELECT t.*, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) ID
FROM #SOMETABLE t
)t2
ORDER BY t2.ID
解决该问题的合理通用方法是按照FK_FIELD_POSITION
的顺序计算(ID,FK_FIELD_POSITION)
减少的次数。
EG
drop table if exists #SOMETABLE
go
CREATE TABLE #SOMETABLE
(
ID INT PRIMARY KEY,
FK_FIELD_NAME VARCHAR,
[VALUE] INT,
[FK_FIELD_POSITION] INT
)
INSERT INTO #SOMETABLE
(ID,FK_FIELD_NAME,[VALUE],[FK_FIELD_POSITION])
VALUES
(1,'A',1,17),
(2,'B',3,18),
(3,'C',5,19),
(4,'A',90,17),
(5,'B',15,18),
(6,'C',21,19),
(7,'A',31,17),
(8,'B',75,18),
(9,'C',82,19);
with q as
(
SELECT *, case when fk_field_position < LAG(fk_field_position) over (order by id,fk_field_position) then 1 else 0 end groupStart
FROM #SOMETABLE
)
select *, 1+sum(groupStart) over (order by id) groupNum
from q
输出
ID FK_FIELD_NAME VALUE FK_FIELD_POSITION groupStart groupNum
----------- ------------- ----------- ----------------- ----------- -----------
1 A 1 17 0 1
2 B 3 18 0 1
3 C 5 19 0 1
4 A 90 17 1 2
5 B 15 18 0 2
6 C 21 19 0 2
7 A 31 17 1 3
8 B 75 18 0 3
9 C 82 19 0 3
(9 rows affected)
这里是一种将'A'视为意甲中的第一个方法。然后将相同的等级分配给非'A'。
这也意味着,如果跟随'D'或'E'或其他非'A'的方法,此方法仍然有效。
CREATE TABLE #SOMETABLE ( ID INT IDENTITY(1,1) PRIMARY KEY, FIELD VARCHAR(30), VALUE INT ); INSERT INTO #SOMETABLE (FIELD,VALUE) VALUES ('A',1), ('B',3), ('C',5), ('A',90),('B',15),('C',21), ('A',31),('B',75),('C',82); GO
9行受影响
SELECT * , SUM(CASE WHEN FIELD='A' THEN 1 ELSE 0 END) OVER (ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Rnk FROM #SOMETABLE ORDER BY ID GO
ID |领域|值|排行-:| :---- | ----:| -:1 | A | 1 | 1个2 | B | 3 | 1个3 | C | 5 | 1个4 | A | 90 | 25 | B | 15 | 26 | C | 21 | 27 | A | 31 | 38 | B | 75 | 39 | C | 82 | 3
db <>小提琴here