SQL SERVER 實現相同記錄為空顯示(多列去除重復值,相同的只顯示一條數據)


sql server語句查詢中碰到結果集有重復數據,需要把這個重復數據匯總成一條顯示。其余則正常顯示。

使用SQL內置函數 ROW_NUMBER() 加 PARTITION 完成

ROW_NUMBER() OVER ( PARTITION BY '相同數據字段' ORDER BY GETDATE() ) row

PARTITION BY和GROUP BY類似。

GROUP BY會影響行數,針對於所有字段進行一個聚合。

PARTITION BY則不會影響行數,用做於此處剛剛好。

例:查詢出字段有A、B、C、D、E。其中A代表姓名、B代表年齡、C代碼性別、D代表愛好、E代表喜歡游戲。

其中A、B、C,這三個字段中有重復字段,而D、E則無重復字段。

那么語句便可以這樣寫

SELECT *,ROW_NUMBER() OVER ( PARTITION BY A,B,C ORDER BY GETDATE() ) row FROM tab

這樣你便會看到你的結果中row字段會依據A、B、C三個字段依據不同值分別做一個分組。

A B C D E row
小明 18 1 籃球 LOL 1
小明 18 1 乒乓球 DNF 2
小黃 18 2 游泳 LOL 1
小黃 18 2 滑板 QQ飛車 2
小黃 18 2 跑步 戰地五 3
小孫 18 1 睡覺 劍網三 1

 

 

 

 

 

 

 

 

 

所以以上數據便是依據PARTITION BY分組所顯示行號。

既然已經得到這樣的數據,那么把相同的數據更改為空就很簡單了。使用CASE WHEN便可以實現。

SELECT  CASE WHEN row = 1 THEN T.A
             ELSE ''
        END A ,
        CASE WHEN row = 1 THEN T.B
             ELSE ''
        END B ,
        CASE WHEN row = 1 THEN T.C
             ELSE ''
        END C ,
        T.D ,
        T.E
FROM    ( SELECT    * ,
                    ROW_NUMBER() OVER ( PARTITION BY A, B, C ORDER BY GETDATE() ) row
          FROM      tab
        ) T

那么以上語句執行最終結果便是一下表格里的數據:

A B C D E row
小明 18 1 籃球 LOL 1
      乒乓球 DNF 2
小黃 18 2 游泳 LOL 1
      滑板 QQ飛車 2
      跑步 戰地五 3
小孫 18 1 睡覺 劍網三 1

 

 

 

 

 

 

 

 

 

這樣一來就簡介多了,SQL SERVER很多內置函數還是非常好用的。

 

最后放上一個測試臨時表格供大家測試吧!

CREATE TABLE #tab
    (
      headerNo VARCHAR(10) ,
      machineNO VARCHAR(10) ,
      descrption NVARCHAR(20) ,
      artNo VARCHAR(20) ,
      qty INT ,
      repartno VARCHAR(20) ,
      repqty INT
    )

插入數據

insert INTO #tab SELECT 'HD01','0101520',N'電池出問題','102020',2,'102020',2
insert INTO #tab SELECT 'HD01','0101520',N'電池出問題','101010',2,'202020',2
insert INTO #tab SELECT 'HD01','0101520',N'電池出問題','126888',2,'102020',2
insert INTO #tab SELECT 'HD02','01012221',N'D電機故障','102020',2,'102020',2
insert INTO #tab SELECT 'HD03','12312312',N'突然停機','102020',2,'102020',2
insert INTO #tab SELECT 'HD03','12312312',N'突然停機','102020',2,'102020',2
insert INTO #tab SELECT 'HD04','12312344',N'皮帶松了','102020',2,'102020',2

語句查詢執行

SELECT  CASE WHEN row = 1 THEN headerNo
             ELSE ''
        END headerNo ,
        CASE WHEN row = 1 THEN machineNO
             ELSE ''
        END machineNO ,
        CASE WHEN row = 1 THEN descrption
             ELSE ''
        END descrption ,
        artNo ,
        qty ,
        repartno ,
        repqty
FROM    ( SELECT    * ,
                    ROW_NUMBER() OVER ( PARTITION BY headerNo, machineNO,
                                        descrption ORDER BY GETDATE() ) row
          FROM      #tab
        ) M

 

以上測試SQL語句來自博客園以下老哥的文章,它的文章只編寫了SQL語句供予測試。

我加以修改,做了一些理解性的分析。

https://www.cnblogs.com/panxuguang/p/5668520.html

 

后續更新

PARTITION BY簡稱分區函數,GROUP BY為聚合函數。
PARTITION BY的使用之處可以有很多,文章的上半部分查詢出來的數據用於報表非常合適。
但用作於程序中就會顯得比較復雜。
以此可以思考,既然 PARTITION BY是依據當前字段不同的字段做一個分組,不影響數據結構、數據行。
結合ROW_NUMBER對分組后的數據進行一個排序。這樣就可以根據ROU_NUMBER后的字段進行數據查詢。
同時,PARTITION BY 還可以在一個查詢語句中針對於多個字段進行查詢。但后續的PARTITION BY須攜帶上前一個字段。
比如上面例子中再增加一個字段,父母標識。L字段中,0代表自己,1代表母親,2代表父親。D和E就表示父母的愛好。
SELECT  CASE WHEN row = 1 THEN T.A
             ELSE ''
        END A ,
        CASE WHEN row = 1 THEN T.B
             ELSE ''
        END B ,
        CASE WHEN row = 1 THEN T.C
             ELSE ''
        END C ,
     CASE WHEN row2 = 1 THEN T.L
                ELSE ''
        END F,
        T.D ,
        T.E
FROM    ( SELECT    * ,
                    ROW_NUMBER() OVER ( PARTITION BY A, B, C ORDER BY GETDATE() ) row,
                    ROW_NUMBER() OVER ( PARTITION BY A, B, C, L ORDER BY GETDATE() ) row2
          FROM      tab
        ) T   

這樣除了第一次的依據A,B,C進行了一個內部分區排序,
隨后第二次操作就會依據A,B,C為參照針對L的不同字段在做一個內部分區排序。數據就是下面的樣式
A B C L D E
小明 18 1 0 籃球 LOL
        乒乓球 DNF
      2 籃球 吃雞
        跳傘 黎明殺機
      1 跳繩 和平精英
小黃 18 2   游泳 LOL
        滑板 QQ飛車
        跑步 戰地五
小孫 18 1   睡覺 劍網三


















通過PARTITON BY 分區排序之后,你還可以取以什么為條件了前三條,以什么字段為排序的第一條等等操作




 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM