簡體   English   中英

T-SQL:重復和查詢最新的唯一記錄

[英]T-SQL : dedup and query latest unique records

DECLARE @Table TABLE
    (
        [ID]    INT
      , [Alias] NVARCHAR(50)
      , [Key]   INT
      , [Val]   NVARCHAR(10)
      , [RN]    INT
    )

INSERT INTO @Table ([ID], [Alias], [Key], [Val], [RN])
VALUES
    ( 1, N'A1', 1, N'One', 1 )
  , ( 1, N'A1', 2, N'Two', 1 )
  , ( 1, N'A1', 3, N'', 1 )
  , ( 1, N'A2', 1, N'One', 2 )
  , ( 1, N'A2', 2, N'', 2 )
  , ( 1, N'A2', 3, N'Three', 2 )
  , ( 1, N'A3', 1, N'One', 3 )
  , ( 1, N'A3', 2, N'Two', 3 )
  , ( 1, N'A3', 4, N'Four_New', 3 )
  , ( 1, N'A4', 4, N'Four', 4 )
  , ( 1, N'A4', 5, N'Five', 4 )

  , ( 2, N'B1', 1, N'', 1 )
  , ( 2, N'B1', 2, N'', 1 )
  , ( 2, N'B1', 3, N'', 1 )
  , ( 2, N'B2', 1, N'One', 2 )
  , ( 2, N'B2', 2, N'', 2 )
  , ( 2, N'B2', 3, N'', 2 )
  , ( 2, N'B3', 2, N'Two', 3 )
  , ( 2, N'B3', 4, N'Four', 3 )
  , ( 2, N'B4', 3, N'Three', 4 )
  , ( 2, N'B4', 6, N'Six', 4 )

/* OUTPUT # 1
    ID Alias Key    Val
    1  A5    1      One         -- Kept the Val from Alias = A1
    1  A5    2      Two         -- Kept the Val from Alias = A1
    1  A5    3                  -- Kept the Val from Alias = A1
    1  A5    4      Four_New    -- Taking the Key/Val from Alias = A3 and assigned it to Alias = A1 for ID = 1
    1  A5    5      Five        -- Taking the Key/Val from Alias = A4 and assigned it to Alias = A1 for ID = 1

    2  B5    1                  -- Kept the Val from Alias = B1
    2  B5    2                  -- Kept the Val from Alias = B1
    2  B5    3                  -- Kept the Val from Alias = B1
    2  B5    4      Four        -- Taking the Key/Val from Alias = B3 and assigned it to Alias = B1 for ID = 2
    2  B5    6      Six         -- Taking the Key/Val from Alias = B4 and assigned it to Alias = B1 for ID = 1
*/


/* OUTPUT #2
ID Alias Key    Val
1  A5    1      One         -- Kept the Val from Alias = A1
1  A5    2      Two         -- Kept the Val from Alias = A1
1  A5    3      Three       -- Taking the Val from Alias = A2 because it's the 1st (based on RN ASC) latest filled value for Key = 3 for ID = 1
1  A5    4      Four_New    -- Got the Key/Val from Alias = A3 and assigned it to Alias = A1
1  A5    5      Five        -- Got the Key/Val from Alias = A4 and assigned it to Alias = A1

2  B5    1      One         -- Taking the Val from Alias = B2 because it's the 1st (based on RN ASC) latest filled value for Key = 1 for ID = 2
2  B5    2      Two         -- Taking the Val from Alias = B3 because it's the 1st (based on RN ASC) latest filled value for Key = 2 for ID = 2
2  B5    3      Three       -- Taking the Val from Alias = B4 because it's the 1st (based on RN ASC) latest filled value for Key = 3 for ID = 2
2  B5    4      Four        -- Got the Key/Val from Alias = B3 and assigned it to Alias = B1
2  B5    6      Six         -- Got the Key/Val from Alias = B4 and assigned it to Alias = B1
*/

描述:這是真實表的示例數據表示形式,恰好很大。

領域:

  • ID =人員的唯一ID
  • Alias =每次再次創建同一人的條目時,都會給他/他新的別名
  • Key =描述此人的財產
  • Value =該屬性的值
  • RN =創建人員條目的時間順序-1為最新,2為第二最新,依此類推。

目標:

兩個輸出

輸出#1合並所有匹配人員的記錄,並創建一個全新的人員,該人員將從該人員的最新條目中獲取所有鍵/值數據,並添加先前條目中所有丟失的鍵/值(始終取最新的鍵/值)。

輸出#2合並所有匹配人員的記錄,並創建一個全新的人員,該人員將從該人員的最新條目中獲取所有非(空/空)鍵/值數據,並添加先前條目中所有丟失的鍵/值(始終取最新的鍵/值)

我會選擇以下結果的排名

對於輸出#1

with base_rows
  as (select *
            ,rank() over(partition by id,[key] order by rn asc) as rnk
            ,cast(max(substring(alias,2,len(alias))) over(partition by id)+1 as nvarchar(100)) as max_index
            ,max(substring(alias,1,1)) over(partition by id) as alias_char
        from t
      )
 select id
        ,concat(alias_char,max_index)
        ,[key]
        ,[val]
        ,[rn]
   from base_rows
  where rnk=1


+----+------------------+-----+----------+----+
| id | (No column name) | key |   val    | rn |
+----+------------------+-----+----------+----+
|  1 | A5               |   1 | One      |  1 |
|  1 | A5               |   2 | Two      |  1 |
|  1 | A5               |   3 |          |  1 |
|  1 | A5               |   4 | Four_New |  3 |
|  1 | A5               |   5 | Five     |  4 |
|  2 | B5               |   1 |          |  1 |
|  2 | B5               |   2 |          |  1 |
|  2 | B5               |   3 |          |  1 |
|  2 | B5               |   4 | Four     |  3 |
|  2 | B5               |   6 | Six      |  4 |
+----+------------------+-----+----------+----+

對於輸出2

除了我們過濾掉base_rows塊中所有為空的記錄外,它與output#1的查詢相同。

with base_rows
  as (select *
            ,rank() over(partition by id,[key] order by rn asc) as rnk
            ,cast(max(substring(alias,2,len(alias))) over(partition by id)+1 as nvarchar(100)) as max_index
            ,max(substring(alias,1,1)) over(partition by id) as alias_char
        from t
      where [val] <> ''  
      )
 select id
        ,concat(alias_char,max_index)
        ,[key]
        ,[val]
        ,[rn]
   from base_rows
 where rnk=1



+----+------------------+-----+----------+----+
| id | (No column name) | key |   val    | rn |
+----+------------------+-----+----------+----+
|  1 | A5               |   1 | One      |  1 |
|  1 | A5               |   2 | Two      |  1 |
|  1 | A5               |   3 | Three    |  2 |
|  1 | A5               |   4 | Four_New |  3 |
|  1 | A5               |   5 | Five     |  4 |
|  2 | B5               |   1 | One      |  2 |
|  2 | B5               |   2 | Two      |  3 |
|  2 | B5               |   3 | Three    |  4 |
|  2 | B5               |   4 | Four     |  3 |
|  2 | B5               |   6 | Six      |  4 |
+----+------------------+-----+----------+----+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM