TSQL基于条件的第二个标记,但也基于其他标记

问题描述 投票:1回答:1

尝试实现一些代码,我创建两个标记条件结束的列。我将从代码开始:

CREATE TABLE #SampleT (ID INT, SomeVal VARCHAR (10))
INSERT INTO #SampleT VALUES (10, 'X') 
INSERT INTO #SampleT VALUES (20, 'X')
INSERT INTO #SampleT VALUES (30, 'X')
INSERT INTO #SampleT VALUES (40, 'Y')
INSERT INTO #SampleT VALUES (50, 'Y')
INSERT INTO #SampleT VALUES (60, 'Y')
INSERT INTO #SampleT VALUES (70, 'W')
INSERT INTO #SampleT VALUES (80, 'W')
INSERT INTO #SampleT VALUES (90, 'W')
INSERT INTO #SampleT VALUES (100, 'Z')
INSERT INTO #SampleT VALUES (110, 'Z')
INSERT INTO #SampleT VALUES (120, 'Z')

WITH CTE AS 

(
    SELECT ID, 
         SomeVal,
         ROW_NUMBER() OVER (ORDER BY SomeVal) AS RowNumb
    FROM #SampleT AS S
)

SELECT C.*, 
      CASE WHEN C.SomeVal <> C2.SomeVal THEN '**' ELSE '' END AS EndMarking,
      (C.RowNumb / 11) + 1 AS SecondEndMarking
FROM CTE AS C
LEFT JOIN CTE AS C2 ON C.RowNumb = C2.RowNumb - 1
ORDER BY C.RowNumb

DROP TABLE #SampleT

基本上,这段代码工作正常。但我希望第二个结束标记从列Endmarking的前一个标记开始。在这个例子中,我希望SecondEndMarking列在第9行从1变为2,因为那是前一个Enmarking用**填充的时候。

期望的结果:

ID  SomeVal RowNumb EndMarking  SecondEndMarking
70  W   1       1
80  W   2       1
90  W   3   **  1
10  X   4       1
20  X   5       1
30  X   6   **  1
40  Y   7       1
50  Y   8       1
60  Y   9   **  2
100 Z   10      2
110 Z   11      2
120 Z   12      2

这可能听起来有点模糊,但是如上所述的示例代码和所需的输出,我希望有人可以帮助我!

谢谢。

sql-server tsql sql-server-2008
1个回答
1
投票

如果我理解正确,你可以试试这个。

由于sql-server 2008不支持LEAD函数你可以尝试使用子查询来达到LEAD函数效果

CREATE TABLE SampleT (ID INT, SomeVal VARCHAR (10))
INSERT INTO SampleT VALUES (10, 'X') 
INSERT INTO SampleT VALUES (20, 'X')
INSERT INTO SampleT VALUES (30, 'X')
INSERT INTO SampleT VALUES (40, 'Y')
INSERT INTO SampleT VALUES (50, 'Y')
INSERT INTO SampleT VALUES (60, 'Y')
INSERT INTO SampleT VALUES (70, 'W')
INSERT INTO SampleT VALUES (80, 'W')
INSERT INTO SampleT VALUES (90, 'W')
INSERT INTO SampleT VALUES (100, 'Z')
INSERT INTO SampleT VALUES (110, 'Z')
INSERT INTO SampleT VALUES (120, 'Z')

查询1:

;WITH CTE AS 
(
    SELECT ID, 
         SomeVal,
         ROW_NUMBER() OVER (ORDER BY SomeVal) AS RowNumb
    FROM SampleT t1
)
SELECT *,(CASE WHEN MAX(CASE WHEN EndMarking ='**' THEN RowNumb END) OVER (ORDER BY RowNumb DESC) > RowNumb THEN 1 ELSE 2 END) SecondEndMarking
FROM (
  SELECT *,CASE WHEN ( SELECT top 1 SomeVal 
      FROM cte tt
      WHERE tt.RowNumb > t1.RowNumb
      ORDER BY SomeVal )  <> SomeVal  THEN '**'
  ELSE '' END EndMarking  
  FROM CTE t1
) t1
order by RowNumb

Results

|  ID | SomeVal | RowNumb | EndMarking | SecondEndMarking |
|-----|---------|---------|------------|------------------|
|  70 |       W |       1 |            |                1 |
|  80 |       W |       2 |            |                1 |
|  90 |       W |       3 |         ** |                1 |
|  10 |       X |       4 |            |                1 |
|  20 |       X |       5 |            |                1 |
|  30 |       X |       6 |         ** |                1 |
|  40 |       Y |       7 |            |                1 |
|  50 |       Y |       8 |            |                1 |
|  60 |       Y |       9 |         ** |                2 |
| 100 |       Z |      10 |            |                2 |
| 110 |       Z |      11 |            |                2 |
| 120 |       Z |      12 |            |                2 |
© www.soinside.com 2019 - 2024. All rights reserved.