我有以下结果集。
Tmp_Table
Tag | Code | Rel
A ABC 1
A ABC 1
A ABC 1
A ABC 1
B XYZ 1
B XYZ 1
B XYZ 1
B XYZ 1
B XYZ 1
C QWE 1
C QWE 1
C QWE 1
D EFG 1
要求是:
我尝试使用dense_rank()
为每条记录创建一个简单的增量。
SELECT DENSE_RANK() OVER(Order By Tag)groupID, * FROM Tmp_Table
这是当前的结果集。
groupID | Tag | Code | Rel
1 A ABC 1
1 A ABC 1
1 A ABC 1
1 A ABC 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
3 C QWE 1
3 C QWE 1
3 C QWE 1
4 D EFG 1
预期结果。
groupID | Tag | Code | Rel
1 A ABC 1
1 A ABC 1
1 A ABC 1
1 A ABC 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
3 B XYZ 1
4 C QWE 1
4 C QWE 1
4 C QWE 1
5 D EFG 1
我还尝试仅使用row_number() over (partition by Tag order by Tag)
为每个标记添加增量。
groupID | Tag | Code | Rel
1 A ABC 1
2 A ABC 1
3 A ABC 1
4 A ABC 1
1 B XYZ 1
2 B XYZ 1
3 B XYZ 1
4 B XYZ 1
5 B XYZ 1
...
肯定遗漏了一些重要的事情。任何想法都将非常感谢!
答案 0 :(得分:0)
实际上,你应该在你的行中有一些定义功能,以确保顺序是正确的(并且,通常,数据中的重复没有任何关于行的任何独特性是多余的),但没有它,这是一种方式你可以使用窗口函数的组合(假设SQL Server 2012 +):
DECLARE @T TABLE (Tag CHAR(1), Code CHAR(3), Rel INT);
INSERT @T VALUES
('A', 'ABC', 1),
('A', 'ABC', 1),
('A', 'ABC', 1),
('A', 'ABC', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('C', 'QWE', 1),
('C', 'QWE', 1),
('C', 'QWE', 1),
('D', 'EFG', 1);
SELECT GroupID = SUM(RN2) OVER (ORDER BY RN1), Tag, Code, Rel
FROM
(
SELECT *, RN2 = CASE WHEN ROW_NUMBER() OVER (PARTITION BY Tag ORDER BY RN1) % 4 = 1 THEN 1 ELSE 0 END
FROM (
SELECT *, RN1 = ROW_NUMBER() OVER (ORDER BY Tag)
FROM @T
) AS T
) AS T;
答案 1 :(得分:0)
这是另一种选择......
IF OBJECT_ID('tempdb..#tmp_table', 'U') IS NOT NULL
DROP TABLE #tmp_table;
CREATE TABLE #tmp_table (
Tag CHAR(1),
Code CHAR(3),
Rel TINYINT
);
INSERT #tmp_table (Tag, Code, Rel) VALUES
('A', 'ABC', 1),
('A', 'ABC', 1),
('A', 'ABC', 1),
('A', 'ABC', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('B', 'XYZ', 1),
('C', 'QWE', 1),
('C', 'QWE', 1),
('C', 'QWE', 1),
('D', 'EFG', 1);
--=============================================
WITH
cte_AddRN AS (
SELECT
tt.Tag, tt.Code, tt.Rel,
RN = ROW_NUMBER() OVER (PARTITION BY tt.Tag ORDER BY (SELECT NULL))
FROM
#tmp_table tt
)
SELECT
GroupID = DENSE_RANK() OVER (ORDER BY gv.GroupVal),
ar.Tag, ar.Code, ar.Rel
FROM
cte_AddRN ar
CROSS APPLY ( VALUES (ISNULL(NULLIF(ar.RN, 0), 4)) ) r (RN)
CROSS APPLY ( VALUES (ISNULL(NULLIF(r.RN % 4, 0), 4)) ) m (ModRN)
CROSS APPLY ( VALUES (ar.Tag + CAST(r.RN - m.ModRN AS VARCHAR(10))) ) gv (GroupVal);
结果...
GroupID Tag Code Rel
-------------------- ---- ---- ----
1 A ABC 1
1 A ABC 1
1 A ABC 1
1 A ABC 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
2 B XYZ 1
3 B XYZ 1
4 C QWE 1
4 C QWE 1
4 C QWE 1
5 D EFG 1
答案 2 :(得分:0)
我的#tmp_table
包含您提供的数据。解决方案如下:
我添加标签1以记录超过四个,因此在此标记上您可以直接应用dense_rank()
。
select GroupID = dense_rank() over (order by OverFour), tag, code, rel from (
select case when rn < 5 then tag + '0' else tag + '1' end as OverFour,
tag, code, rel
from (
select rn = row_number() over (partition by tag order by tag),
tag, code, rel
from #tmp_table
) as a
) as b