2017-05-18 47 views
1

我有這個表:查詢SQL Server中的重複記錄?

+----------+----------+---------+-----------------------------------+ 
| Class A | Class B | Class C | Result_XML      | 
+----------+----------+---------+-----------------------------------+ 
| SUPER | PREMIUM | A  | <Array> <Ser ref="RF124" r="200」> | 
| ECONOMIC | SEMI  | A  | <Array> <Ser ref="RF124" r="200」> | 
| SUPER | PREMIUM | A  | <Array> <Ser ref="RF144" r="500」> | 
| SUPER | NA  | B  | <Array> <Ser ref="RF124" r="200」> | 
| ECONOMIC | SEMI  | A  | <Array> <Ser ref="RF154" r="200」> | 
| SUPER | PREMIUM | C  | <Array> <Ser ref="RF124" r="100」> | 
+----------+----------+---------+-----------------------------------+ 

而且,我一直試圖得到的是類似如下:

+----------+---------+--------+---------+ 
| ClassA | ClassB | ClassC | Result | 
+----------+---------+--------+---------+ 
| SUPER | PREMIUM | A  | 200,500 | 
| ECONOMIC | SEMI | A  |  200 | 
| SUPER | NA  | B  |  200 | 
| SUPER | PREMIUM | C  |  100 | 
+----------+---------+--------+---------+ 

基本上上面是從第一臺具有相同的結果記錄不同的列表在最後一列中,如果不同則將結果填入同一行,如第一個例子。到目前爲止,我提出了以下,但顯然不工作。預先感謝您的幫助:

SELECT DISTINCT 
    ClassA, ClassB, ClassC, 
    Result = (STUFF((Select Distinct ',' + E1.RESULT_XML.value('(/Array/Ser/@r)[1]', 'varchar(max)') 
        From listtable E2 
        Where E1.ClassA = E2.ClassA 
         And E1.ClassB = E2.ClassB 
         And E1.ClassC = E2.ClassC 
        FOR XML PATH(''), TYPE, ROOT).value('root[1]','nvarchar(max)'),1,1,'')) 
FROM 
    listtable E1 
+0

對不起STANGE看錶......我轉換表從Excel到ASCII格式,但仍無法正常顯示的SQL Server – Nomdeplume

+0

什麼版本? – Kapil

+0

sql server 2012 – Nomdeplume

回答

0

我有一個解決問題的辦法,但我敢肯定,它可以更有效地解決。

 
SELECT 
    ClassA 
    ,ClassB 
    ,ClassC 
    ,Result = (STUFF((SELECT DISTINCT 
      ',' + CAST(E1.Result AS XML).value('(/Array/Ser/@r)[1]', 'varchar(max)') 
     FROM [OrchestratorNotifications].[dbo].[Kuko] E2 
     WHERE E1.ClassA = E2.ClassA 
     AND E1.ClassB = E2.ClassB 
     AND E1.ClassC = E2.ClassC 
     FOR XML PATH (''), TYPE, ROOT) 
    .value('root[1]', 'nvarchar(max)'), 1, 1, '')) INTO #tmp1 
FROM [OrchestratorNotifications].[dbo].[Kuko] E1 
ORDER BY ClassA 
    ,ClassB 
    ,ClassC 

SELECT ClassA 
    ,ClassB 
    ,ClassC 
    ,Result FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY ClassA,ClassB,ClassC ORDER BY ClassA,ClassB,ClassC,w DESC) AS r1 FROM( 
SELECT 
    ClassA 
    ,ClassB 
    ,ClassC 
    ,o.Result, 
    o.w, 
    ROW_NUMBER() OVER(PARTITION BY ClassA,ClassB,ClassC,o.w ORDER BY ClassA,ClassB,ClassC,o.w) AS rownum 
FROM #tmp1 a 
CROSS APPLY (SELECT 
     CASE 
      WHEN a.Result = b.Result THEN a.Result 
      ELSE a.Result + ',' + b.Result 
     END Result, 
      CASE 
      WHEN CAST(a.Result AS INT) = CAST(b.Result AS INT) THEN CAST(a.Result AS INT) 
      ELSE CAST(a.Result AS INT) + CAST(b.Result AS INT) 
     END w 
    FROM #tmp1 b 
    WHERE a.ClassA = b.ClassA 
    AND a.ClassB = b.ClassB 
    AND a.ClassC = b.ClassC) o 
    )y 
    where y.rownum=1 
    )d 
    WHERE d.r1=1 
    ORDER BY d.ClassC 

DROP TABLE #tmp1 
+0

它給我的結果正是我想要的 - 謝謝。現在我需要了解它是如何工作的:-) – Nomdeplume

1

您應該在東西查詢中使用E2.ResultXml而不是E1.ResultXml。

DECLARE @T TABLE (ClassA NVARCHAR(50), ClassB NVARCHAR(50), ClassC NVARCHAR(50), ResultXML NVARCHAR(300)) 

INSERT @T SELECT 'SUPER','PREMIUM' ,'A','200'--'<Array> <Ser ref="RF124" r="200」>' 
INSERT @T SELECT 'ECONOMIC','SEMI' ,'A','200'--'<Array> <Ser ref="RF124" r="200」>' 
INSERT @T SELECT 'SUPER','PREMIUM' ,'A','500'--'<Array> <Ser ref="RF144" r="500」>' 
INSERT @T SELECT 'SUPER','NA'  ,'B','200'--'<Array> <Ser ref="RF124" r="200」>' 
INSERT @T SELECT 'ECONOMIC','SEMI' ,'A','200'--'<Array> <Ser ref="RF154" r="200」>' 
INSERT @T SELECT 'SUPER','PREMIUM' ,'C','100'--'<Array> <Ser ref="RF124" r="100」>' 

SELECT * FROM @T 


SELECT 
    ClassA,ClassB,ClassC, 
    Result = (STUFF((Select DISTINCT ',' + E2.RESULTXML 
        From @T E2 
        Where E1.ClassA = E2.ClassA 
         And E1.ClassB = E2.ClassB 
         And E1.ClassC = E2.ClassC 
        FOR XML PATH('')),1,1,'')) 
FROM 
    @T E1 
GROUP BY 
    ClassA, ClassB, ClassC 

產量--->

ClassA  ClassB  ClassC Result 
ECONOMIC SEMI  A  200 
SUPER  NA   B  200 
SUPER  PREMIUM A  200,500 
SUPER  PREMIUM C  100 
0
;with cte(ClassA , ClassB , ClassC , Result_XML) 
AS 
(
SELECT 'SUPER' , 'PREMIUM' , 'A'  , '<Array> <Ser ref="RF124" r="200」>' Union all 
SELECT 'ECONOMIC' , 'SEMI'  , 'A'  , '<Array> <Ser ref="RF124" r="200」>' Union all 
SELECT 'SUPER' , 'PREMIUM' , 'A'  , '<Array> <Ser ref="RF144" r="500」>' Union all 
SELECT 'SUPER' , 'NA'  , 'B'  , '<Array> <Ser ref="RF124" r="200」>' Union all 
SELECT 'ECONOMIC' , 'SEMI'  , 'A'  , '<Array> <Ser ref="RF154" r="200」>' Union all 
SELECT 'SUPER' , 'PREMIUM' , 'C'  , '<Array> <Ser ref="RF124" r="100」>' 
) 

,Result AS (
    SELECT ClassA 
     ,ClassB 
     ,ClassC 
     ,CAST(REPLACE(RIGHT(Result_XML, 5), '」>', '') AS INT) AS Result_XML 
    FROM cte 
    ) 

SELECT DISTINCT ClassA 
    ,ClassB 
    ,ClassC 
    ,STUFF((
      SELECT DISTINCT ', ' + CAST(i.Result_XML AS VARCHAR(10)) 
      FROM Result i 
      WHERE i.ClassA = o.ClassA 
       AND i.ClassB = o.ClassB 
       AND i.ClassC = o.ClassC 
      FOR XML PATH('') 
      ), 1, 1, '') AS Result 
FROM Result o 
ORDER BY ClassC 
    ,Result DESC 

輸出

+----------+---------+--------+---------+ 
| ClassA | ClassB | ClassC | Result | 
+----------+---------+--------+---------+ 
| SUPER | PREMIUM | A  | 200,500 | 
| ECONOMIC | SEMI | A  |  200 | 
| SUPER | NA  | B  |  200 | 
| SUPER | PREMIUM | C  |  100 | 
+----------+---------+--------+---------+