分组范围内的列

时间:2017-05-30 06:12:50

标签: sql sql-server sql-server-2008

我有以下数据(只有A和B列。我的架构中没有C列。)

A   | B   |  C  | 
________________
1     2     G1
2     70    G1
3     91    G1
4     25    G2
5     30    G2 
6     95    G2
7     91    G3
8     75    G4
9     92    G4
10    93    G5

请注意:我想将数据分组在0到90的范围内,即0到90之间的数据将被分组到一个组中。下一组将持续到下一个90.因此每个组的范围为0到90.

我在Column C中提到了我的期望,我正在使用SQL Server 2008。

2 个答案:

答案 0 :(得分:3)

首先使用ROW_NUMBER()我为>90值分配组ID值,然后按下一个组ID值填充NULL值。

使用给定的样本数据执行示例:

DECLARE @TestTable TABLE  (A INT, B INT, C VARCHAR (3));

INSERT INTO @TestTable (A, B) 

SELECT 1 , 2  UNION
SELECT 2 , 70 UNION
SELECT 3 , 91 UNION
SELECT 4 , 25 UNION
SELECT 5 , 30 UNION
SELECT 6 , 95 UNION
SELECT 7 , 91 UNION
SELECT 8 , 75 UNION
SELECT 9 , 92 UNION
SELECT 10, 93;

UPDATE T
SET T.C = R.GRow
FROM @TestTable T
JOIN (  SELECT A, B, 'G' + CAST(ROW_NUMBER() OVER (ORDER BY A) AS VARCHAR (3)) AS GRow  
        FROM @TestTable
        WHERE B > 90 ) R ON R.B = T.B AND R.A = T.A;

UPDATE TT
SET TT.C = RR.GVal
FROM @TestTable TT 
JOIN (  SELECT A, B, ISNULL(C, (SELECT TOP 1 C FROM @TestTable WHERE A > TE.A AND C IS NOT NULL ORDER BY A ASC)) AS GVal
        FROM @TestTable TE ) RR ON RR.B = TT.B AND RR.A = TT.A;

SELECT * FROM @TestTable

答案 1 :(得分:0)

您可以ROW_NUMBERSUM OVER()像这样计算GroupId

DECLARE @SampleData AS TABLE
(
    A int,
    B int
)

INSERT INTO @SampleData
VALUES 
(1 , 2 ),
(2 , 70),
(3 , 91),
(4 , 25),
(5 , 30), 
(6 , 95),
(7 , 91),
(8 , 75),
(9 , 92),
(10, 93)

;WITH temp AS
(
    SELECT *, Row_number() OVER(ORDER BY A ) AS Rn
    FROM @SampleData sd
)
,temp1 AS
(
    SELECT t.A, t.B, CASE   WHEN t2.B IS NULL OR t2.B > 90 THEN 1
                       ELSE 0
                 END as PreviousCount
    FROM temp t
    LEFT JOIN temp t2 ON t.Rn = t2.Rn + 1  -- previous row
)
SELECT t.A, t.B, 'G' + CAST(sum(t.PreviousCount) over(ORDER BY t.A) AS varchar(5)) AS GroupId
FROM temp1 t

演示链接:http://rextester.com/TXP71819

注意:对于sql-server 2012+,您可以直接使用LAG获取上一行。