2011-01-06 18 views
3

Ich habe eine Tabelle mit 3 Spalten mit einer variablen Anzahl von Datensätzen basierend auf der ersten Spalte, die ein Fremdschlüssel ist. Ich versuche, um zu bestimmen, ob ich erkennen kann, wenn es eine doppelte über mehrere Zeilen für eine ganze Reihefinden Sie eine doppelte Serie in SQL

declare @finddupseries table 
(
    portid int, 
    asset_id int, 
    allocation float 
) 
; 
INSERT INTO @finddupseries 
SELECT 250, 6, 0.05 UNION ALL 
SELECT 250, 66, 0.8 UNION ALL 
SELECT 250, 2, 0.105 UNION ALL 
SELECT 250, 4, 0.0225 UNION ALL 
SELECT 250, 5, 0.0225 UNION ALL 
SELECT 251, 13, 0.6 UNION ALL 
SELECT 251, 2, 0.3 UNION ALL 
SELECT 251, 5, 0.1 UNION ALL 
SELECT 252, 13, 0.8 UNION ALL 
SELECT 252, 2, 0.15 UNION ALL 
SELECT 252, 5, 0.05 UNION ALL 
SELECT 253, 13, 0.4 UNION ALL 
SELECT 253, 2, 0.45 UNION ALL 
SELECT 253, 5, 0.15 UNION ALL 
SELECT 254, 6, 0.05 UNION ALL 
SELECT 254, 66, 0.8 UNION ALL 
SELECT 254, 2, 0.105 UNION ALL 
SELECT 254, 4, 0.0225 UNION ALL 
SELECT 254, 5, 0.0225 

select * from @finddupseries 

Die Aufzeichnungen für portid 250 und 254 Übereinstimmung vorhanden ist.

Gibt es eine Möglichkeit, eine Abfrage zu schreiben, um dies zu erkennen? edit: Ja, die ganze Serie muss übereinstimmen. Auch, wenn es eine Möglichkeit gäbe, zu bestimmen, welche es DID übereinstimmen würde hilfreich sein, da die tatsächliche Tabelle rund 10k Datensätze hat.

danke!

+1

+1 für die Aufnahme von gebrauchsfertigen Beispieldaten. –

+0

@Joe - es ist wie ein Hauch frischer Luft! :) – codingbadger

+0

lol, ich habe in der Vergangenheit in der Vergangenheit dafür geschlagen worden, Testdaten nicht einzuschließen: P –

Antwort

4

Diese Abfrage können Sie die Werte alle in einem von port_id

SELECT fus1.portid, 
(
    SELECT CONVERT (VARCHAR, fus2.asset_id) + CONVERT (VARCHAR, fus2.allocation) + ',' 
    FROM @finddupseries fus2 
    WHERE 1=1 
     AND fus1.portid = fus2.portid 
    ORDER BY fus2.portid, fus2.asset_id, fus2.allocation 
    FOR XML PATH ('') 
) AllValuesFromAllRows 
FROM @finddupseries fus1 
GROUP BY fus1.portid 

die Ausgabe so

portid  AllValuesFromAllRows 
----------- ------------------------------------------------------ 
250   20.105,40.0225,50.0225,60.05,660.8, 
251   20.3,50.1,130.6, 
252   20.15,50.05,130.8, 
253   20.45,50.15,130.4, 
254   20.105,40.0225,50.0225,60.05,660.8, 

gruppiert String umgewandelt geben aussehen sollte

Jetzt, lass uns eine Gruppe mit einem haben!

;With DuplicateFinder as 
(
    SELECT fus1.portid, 
    (
     SELECT CONVERT (VARCHAR, fus2.asset_id) + CONVERT (VARCHAR, fus2.allocation) + ',' 
     FROM @finddupseries fus2 
     WHERE 1=1 
      AND fus1.portid = fus2.portid 
     ORDER BY fus2.portid, fus2.asset_id, fus2.allocation 
     FOR XML PATH ('') 
    ) AllValuesFromAllRows 
    FROM @finddupseries fus1 
    GROUP BY fus1.portid 
) 
SELECT AllValuesFromAllRows, COUNT (*) NumDups 
FROM DuplicateFinder 
GROUP BY AllValuesFromAllRows 
Having COUNT (*) > 1 

Sie sollten

AllValuesFromAllRows       NumDups 
----------------------------------------------- ----------- 
20.105,40.0225,50.0225,60.05,660.8,    2 





bekommen hier also alles zusammen

gesetzt wird
SET NOCOUNT ON 

declare @finddupseries table 
(
    portid int, 
    asset_id int, 
    allocation float 
) 
; 
INSERT INTO @finddupseries 
SELECT 250, 6, 0.05 UNION ALL 
SELECT 250, 66, 0.8 UNION ALL 
SELECT 250, 2, 0.105 UNION ALL 
SELECT 250, 4, 0.0225 UNION ALL 
SELECT 250, 5, 0.0225 UNION ALL 
SELECT 251, 13, 0.6 UNION ALL 
SELECT 251, 2, 0.3 UNION ALL 
SELECT 251, 5, 0.1 UNION ALL 
SELECT 252, 13, 0.8 UNION ALL 
SELECT 252, 2, 0.15 UNION ALL 
SELECT 252, 5, 0.05 UNION ALL 
SELECT 253, 13, 0.4 UNION ALL 
SELECT 253, 2, 0.45 UNION ALL 
SELECT 253, 5, 0.15 UNION ALL 
SELECT 254, 6, 0.05 UNION ALL 
SELECT 254, 66, 0.8 UNION ALL 
SELECT 254, 2, 0.105 UNION ALL 
SELECT 254, 4, 0.0225 UNION ALL 
SELECT 254, 5, 0.0225 

;With PivotAssetIdAndAllocation as 
(
    SELECT fus1.portid, 
    (
     SELECT CONVERT (VARCHAR, fus2.asset_id) + '_'+ CONVERT (VARCHAR, fus2.allocation) + '~~' 
     FROM @finddupseries fus2 
     WHERE 1=1 
      AND fus1.portid = fus2.portid 
     ORDER BY fus2.portid, fus2.asset_id, fus2.allocation 
     FOR XML PATH ('') 
    ) AllValuesFromAllRows 
    FROM @finddupseries fus1 
    GROUP BY fus1.portid 
) 
, 
ListOfDuplicates AS 
(
    SELECT AllValuesFromAllRows, COUNT (*) NumDups 
    FROM PivotAssetIdAndAllocation 
    GROUP BY AllValuesFromAllRows 
    Having COUNT (*) > 1 
) 
SELECT portid, AllValuesFromAllRows 
FROM PivotAssetIdAndAllocation 
WHERE AllValuesFromAllRows IN (SELECT AllValuesFromAllRows FROM ListOfDuplicates) 

und der Ausgang ist

portid  AllValuesFromAllRows 
----------- ---------------------------------------------------------------------- 
250   2_0.105~~4_0.0225~~5_0.0225~~6_0.05~~66_0.8~~ 
254   2_0.105~~4_0.0225~~5_0.0225~~6_0.05~~66_0.8~~ 
+0

+1 Schön gemacht. –

+0

Das ist ein großartiges Stück Arbeit, vielen Dank! –

0

dies den Trick tun sollten:

declare @finddupseries table 
(
    portid int, 
    asset_id int, 
    allocation float 
) 
; 
INSERT INTO @finddupseries 
SELECT 250, 6, 0.05 UNION ALL 
SELECT 250, 66, 0.8 UNION ALL 
SELECT 250, 2, 0.105 UNION ALL 
SELECT 250, 4, 0.0225 UNION ALL 
SELECT 250, 5, 0.0225 UNION ALL 
SELECT 251, 13, 0.6 UNION ALL 
SELECT 251, 2, 0.3 UNION ALL 
SELECT 251, 5, 0.1 UNION ALL 
SELECT 252, 13, 0.8 UNION ALL 
SELECT 252, 2, 0.15 UNION ALL 
SELECT 252, 5, 0.05 UNION ALL 
SELECT 253, 13, 0.4 UNION ALL 
SELECT 253, 2, 0.45 UNION ALL 
SELECT 253, 5, 0.15 UNION ALL 
SELECT 254, 6, 0.05 UNION ALL 
SELECT 254, 66, 0.8 UNION ALL 
SELECT 254, 2, 0.105 UNION ALL 
SELECT 254, 4, 0.0225 UNION ALL 
SELECT 254, 5, 0.0225 UNION ALL 
SELECT 255, 13, 0.6 UNION ALL 
SELECT 255, 2, 0.3 UNION ALL 
SELECT 255, 5, 0.1 

;with cteGetDupes 
as 
(
    SELECT row_number() over (partition by asset_id, allocation 
         order by portid desc, asset_id desc, allocation desc) 
      AS RNDesc 
      , row_number() over (partition by asset_id, allocation 
          order by portid, asset_id, allocation) 
      AS RNAsc 
      , * 
    FROM @finddupseries 
) 
SELECT portid, asset_id, allocation 
FROM cteGetDupes 
WHERE RNDesc - RNAsc != 0 
order by portid, asset_id, allocation 
+0

Sehen Sie meinen Kommentar auf [Barrys Antwort] (http://stackoverflow.com/questions/4616785/find-a-duplicate-series -in-sql/4616868 # 4616868). Ich glaube, Ihre Lösung hat das gleiche Problem. –

+0

nicht das gleiche Problem, aber ähnlich. werde es reparieren ... –

Verwandte Themen