2017-10-24 1 views
0

6 개 이상의 테이블에 조인을 수행하고 조건에 따라 다양한 열을 가져 오는 쿼리가 있습니다. 나는 count(distinct dateCaptured)>30을 가진 회원들에게만 줄 수있는 여분의 필터 조건을 추가하고 싶습니다. 나는 Group byhaving을 사용하여이 조건을 충족시키는 회원 목록을 얻을 수 있습니다. 그러나이 조건 때문에 다른 열 이름으로 그룹화하고 싶지 않습니다. 이 경우 PARTITION BY을 사용해야합니까?그룹을 사용하지 않고 SQL 필터 행을 기반으로

샘플 표

SELECT a.value, 
     b.value, c.value, 
     d.value 
     FROM Table a 
    INNER JOIN Table b on a.Id=b.id 
    INNER JOIN Table c on a.Id=c.Id and s.Invalid=0 
    INNER JOIN Table d on a.Id=d.Id 

표 A는 식별자 37348에 대한 30 개 이상의 레코드가 가정 해 보자

+-----+------------+--------------+ 
| Id | Identifier | DateCaptured | 
+-----+------------+--------------+ 
| 1 |  05548 | 2017-09-01 | 
| 2 |  05548 | 2017-09-01 | 
| 3 |  05548 | 2017-09-01 | 
| 4 |  05548 | 2017-09-02 | 
| 5 |  05548 | 2017-09-03 | 
| 6 |  05548 | 2017-09-04 | 
| 7 |  37348 | 2017-08-15 | 
| 8 |  37348 | 2017-08-15 | 
| . |   |    | 
| . |   |    | 
| . |   |    | 
| 54 |  37348 | 2017-10-15 | 
+-----+------------+--------------+ 

쿼리. 위 쿼리에 대해이 식별자 만 얻는 방법은 무엇입니까?

위의 SELECT에 관심이있는 환자입니다. 여러 행이 정말 tableA에있는 경우

SELECT a.Identifier,count(DISTINCT DateCaptured) 
    FROM Table a 
    INNER JOIN Table b on a.Id=b.id 
    INNER JOIN Table c on a.Id=c.Id and s.Invalid=0 
    INNER JOIN Table d on a.Id=d.Id 
    GROUP BY Identifier 
    HAVING count(DISTINCT DateCaptured)>30 
+0

.... 출력물을 원하는대로 달라집니다. 그리고 당신이 시작하는 조건. 당신은 분명히 어떤 테이블에 대해서도 "DateCaptured"를 집계 할 수 있지만, 계산 된 행을 먼저 줄이면 (즉, 다른 테이블에서도 참조를 가져야 함) 분명하지는 않습니다. 윈도우 화 된 카운트는 카운트하는 것 외에도 모든 단일 날짜를 표시하는 경우에 주로 유용합니다. –

+0

어떤 버전의 SQL Server를 사용하고 있습니까? – Sparrow

+0

@ Clockwork-Muse 첫 번째 쿼리와 동일한 출력입니다. count (distinct dateCaptured)> 30은 30 개 이상의 별개의 날짜를 가진 'Identifier'만 고려하는 필터 조건입니다. – shockwave

답변

1
WITH cte as (
    SELECT a.Identifier 
    FROM Table a 
    INNER JOIN Table b on a.Id=b.id 
    INNER JOIN Table c on a.Id=c.Id and s.Invalid=0 
    INNER JOIN Table d on a.Id=d.Id 
    GROUP BY Identifier 
    HAVING count(DISTINCT DateCaptured) > 30 
) 
SELECT a.value, 
     b.value, c.value, 
     d.value 
FROM Table a 
INNER JOIN Table b on a.Id=b.id 
INNER JOIN Table c on a.Id=c.Id and s.Invalid=0 
INNER JOIN Table d on a.Id=d.Id 
INNER JOIN cte on cte.Identifier = a.Identifier 
1
SELECT a.value, 
     b.value, c.value, 
     d.value 
     FROM Table a 
    INNER JOIN Table b on a.Id=b.id 
    INNER JOIN Table c on a.Id=c.Id and s.Invalid=0 
    INNER JOIN Table d on a.Id=d.Id 
WHERE a.Identifier IN (SELECT a1.Identifier 
    FROM Table a1 
    GROUP BY a1.Identifier HAVING count(DISTINCT a1.DateCaptured)>30) 
+0

은 OP 쿼리와 유사하여 필요한 환자를 복잡하게 만들었습니다. +1 –

1

, 당신은 할 수 있습니다 :

SELECT a.value, b.value, c.value, d.value 
FROM (SELECT a.*, COUNT(*) OVER (PARTITION BY id) as cnt 
     FROM a 
    ) a INNER JOIN 
    b 
    ON a.Id = b.id INNER JOIN 
    c 
    ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
    d 
    ON a.Id = d.Id 
WHERE a.cnt > 30; 

참고 : 당신은 여전히 ​​count(distinct)이 필요하면 당신이 할 수 있습니다

SELECT a.value, b.value, c.value, d.value 
FROM (SELECT a.*, SUM(CASE WHEN seqnum = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY id) as cnt 
     FROM (SELECT a.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY DateCaptured) as seqnum 
      FROM a 
      ) a 
    ) a INNER JOIN 
    b 
    ON a.Id = b.id INNER JOIN 
    c 
    ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
    d 
    ON a.Id = d.Id 
WHERE a.cnt > 30; 
관련 문제