2017-10-24 14 views
0

6つのテーブルでジョインを実行し、条件に基づいてさまざまなカラムをフェッチするクエリがあります。私はcount(distinct dateCaptured)>30を持っているメンバーだけを私に与える特別なフィルター条件を追加したいと思います。私はGroup byhavingを使ってこの条件を満たすメンバーのリストを得ることができます。しかし、私はこの1つの条件のために他の列名でグループ化したくありません。この場合はPARTITION BYを使用する必要がありますか?グループを使用せずにSQLフィルタ行をベースにする

サンプルテーブル

+-----+------------+--------------+ 
| 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 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件の以上のレコードを有していると仮定する。どのように私は上記のクエリのためのこの識別子だけ得ることができます。

私は上記のSELECTに興味がある患者です。

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

複数の行は本当にあなたが行うことができ、tableAにある場合:

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; 
関連する問題