2011-01-06 4 views
3

외부 키인 첫 번째 열을 기반으로하는 다양한 수의 레코드가 포함 된 3 개의 열이있는 테이블이 있습니다. 나는 portid 250 및 254 경기를보기 위해 전체 시리즈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 

레코드의 여러 행에 걸쳐 중복이있을 때 내가 감지 할 수 있는지 확인하려합니다.

이 문제를 감지하는 방법은 없습니까? 편집 : 예, 전체 시리즈가 일치해야합니다. 또한 실제 테이블에 약 10k 개의 레코드가 있으므로 어떤 레코드가 일치했는지 확인하는 방법이 있다면 도움이됩니다.

감사합니다.

+1

+1 즉시 사용할 수있는 샘플 데이터를 포함합니다. –

+0

@Joe - 마치 신선한 공기처럼! :) – codingbadger

+0

롤, 나는 테스트 데이터를 포함하지 않기 때문에 과거에 주위에 때려 봤습니다 : P –

답변

4

이 쿼리는 당신에게 출력이

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, 
과 같아야 포트 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 

별로 그룹화 된 문자열로 변환 모든 값을 줄 것이다

이제 그룹과 함께 할 수 있습니다!

;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 

당신은 그래서 여기

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





모든

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) 

함께 넣어를 받아야하고, 출력은

입니다
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 멋지게 완료되었습니다. –

+0

그건 대단한 작품입니다. 많은 감사합니다! –

0

이 트릭을 수행해야합니다

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

[배리의 대답] (http://stackoverflow.com/questions/4616785/find-a-duplicate-series 내 의견보기 -in-sql/4616868 # 4616868). 나는 당신의 솔루션에 같은 문제가 있다고 생각합니다. –

+0

같은 문제는 아니지만 유사합니다. 그것을 해결하려고 ... –

관련 문제