2017-02-23 1 views
3

의 행 그룹을 일치 나는이 두 데이터베이스에서 다음 (간체) 상황 : I 행의 그룹 (기본 키가 ID 및 PROG 있습니다) 비교해야두 개의 데이터베이스

ID  Prog  T   Qt 
|---------|--------|---------|---------| 
| a  | 1 | N  | 100 | 
| b  | 1 | Y  | 10 | 
| b  | 2 | N  | 90 | 
| c  | 1 | N  | 25 | 
| c  | 2 | Y  | 25 | 
| c  | 3 | Y  | 25 | 
| c  | 4 | Y  | 25 | 
|---------|--------|---------|---------| 

ID  Prog  T   Qt 
|---------|--------|---------|---------| 
| 1  | 1 | Y  | 10 | 
| 1  | 2 | N  | 90 | 
| 2  | 1 | Y  | 100 | 
| 3  | 1 | Y  | 100 | 
| 4  | 1 | Y  | 50 | 
| 4  | 2 | Y  | 25 | 
| 4  | 3 | Y  | 25 |  
|---------|--------|---------|---------| 

(ID를 고려하지 않음) 어떤 행 그룹이 동일한 요소 조합을 나타내는 지 알아내는 것입니다.

위 예제에서 첫 번째 테이블의 ID "b"와 두 번째 테이블의 ID "1"은 Prog, T 및 Qt에 대해 동일한 값 조합을 가지며 다른 하나는 정확히 동일한 것으로 간주 될 수 없습니다. 2 dbs (두 번째 테이블의 ID "2"및 "3"은 동일하지만 동일한 DB에서 비교하는 데는 관심이 없습니다).

나는 모든 것을 설명하기를 바랍니다.

+0

이 몇 SELECT 문보다 더 많은 것을 시도하는 것 같이 내 SQL 명령이 좋지 않다 @iamdave. 나는 일련의 SELECT * FROM ... JOIN ... ON ... WHERE에 의존하지 않고 첫 번째 테이블의 모든 ID에 대해 가능한 결과를 가져 오기 위해 함수 또는 저장 프로 시저를 사용해야한다고 생각합니다. 진실은, 나는이 사이트와 다른 곳에서 무언가를 수색했지만 아무도이 주제에 대해 아무 것도 말하지 않은 것 같다. 일치하는 값은 2 가지입니다. 그래서 나는 깔끔하고 우아한 것을 찾고있었습니다. – MaZe

답변

3

은 가입 및 집계는이 목적을 위해 작동합니다 :

select t1.id, t2.id 
from (select t1.*, count(*) over (partition by id) as cnt 
     from t1 
    ) t1 join 
    (select t2.*, count(*) over (partition by id) as cnt 
     from t2 
    ) t2 
    on t1.prog = t2.prog and t1.T = t2.T and t1.Qt = t2.Qt and t1.cnt = t2.cnt 
group by t1.id, t2.id, t1.cnt 
having count(*) = t1.cnt; 

이 조금 까다 롭습니다. 하위 쿼리는 각 테이블의 각 ID에 대한 행 수를 계산합니다. on 절은 3 개의 열 사이에서 일치를 얻고 ID가 동일한 수를 갖는지 확인합니다. group byhaving은 일치하는 행의 수가 총 행 수인 행을 가져옵니다.

+0

Gordon에게 감사드립니다. 나는 첫 번째 테이블의 각 조합에 대해 동일한 수의 행을 가진 조합 만 확인해야합니다. 나는 그것을 볼 것이다. Wes H에게 편지를 썼을 때, 저는 수십개의 가치에 합류하는 것보다 더 우아한 것을 찾고 싶습니다. 그러나 SQL에 아무런 도움이되지 않는다면 나는 둘 중 하나와 함께 갈 것입니다! – MaZe

+1

@MaZe. . . 다른 데이터베이스에서는'listagg()','group_concat()'또는 유사한 것을 사용합니다. SQL Server에서이 작업을 수행 할 수는 있지만이 솔루션이 훨씬 덜 우아합니다. –

1

일치시킬 조건에 따라 두 테이블을 결합하십시오. 결과는 둘 사이에 일치하는 값이됩니다.

CREATE TABLE a (ID CHAR(1), Prog INT, T CHAR(1), Qt INT); 
CREATE TABLE b (ID int, Prog INT, T CHAR(1), Qt INT); 

    INSERT INTO dbo.a 
      (ID ,Prog ,T ,Qt) 
    VALUES ('a',1,'N',100), ('b',1,'Y',10), ('b',2,'N',90),('c',1,'N',25),('c',2,'Y',25),('c',3,'Y',25),('c',4,'Y',25) 
    INSERT INTO dbo.b 
      (ID ,Prog ,T ,Qt) 
    VALUES (1,1,'Y',10),(1,2,'N',90),(2,1,'Y',100),(3,1,'Y',100),(4,1,'Y',50),(4,2,'Y',25),(4,3,'Y',25) 

WITH CTEa 
AS (SELECT ID, 
      Prog, 
      T, 
      Qt, 
      Cnt = COUNT(ID) OVER (PARTITION BY ID) 
    FROM dbo.a 
    ), 
    CTEb 
AS (SELECT ID, 
      Prog, 
      T, 
      Qt, 
      Cnt = COUNT(ID) OVER (PARTITION BY ID) 
    FROM dbo.b 
    ) 
SELECT ID_A = a.ID, 
     ID_B = b.ID, 
     b.Prog, 
     b.T, 
     b.Qt, 
     b.Cnt 
FROM CTEa AS a 
    INNER JOIN CTEb AS b 
    ON a.Prog = b.Prog 
     AND a.T = b.T 
     AND a.Qt = b.Qt 
     AND a.Cnt = b.Cnt; 

결과 :

ID_A ID_B Prog T Qt Cnt 
b  1  1  Y 10 2 
b  1  2  N 90 2 
+0

이것은 유용합니다. 2 가지 값을 합치려면 많은 작업이 될 수 있다고 생각합니다. 그러나이 경우 나 Gordon Linoff 솔루션을 사용하면 더 좋은 점이 없을 것입니다. 감사! – MaZe

+1

@MaZe 'c'와 '4'가 일치하지 않아야한다고 생각했습니다. – SqlZim

+0

@SqlZim 당신은 완전히 옳습니다. 나는 결과 테이블 전체를 체크하지 않았으며 단지 "b"와 "1"만 같았다. 실제로, 내가 보았으니, Gordon 솔루션을 더 잘 만들어주는 것은 정확히 동일한 수의 행을 검사한다는 사실입니다. 내가 그것을 보게 해줘서 고마워! – MaZe