2017-05-29 18 views
2

私は現在、ビジネスロジックを記述して、IDとそれに追加したフラグを持つテーブルから行を取得するのに問題があります。例えば SQL条件に基づいて行を取得する

id: id seq num: flag: Date: 
A  1    N  .. 
A  2    N  .. 
A  3    N 
A  4    Y 
B  1    N 
B  2    Y 
B  3    N 
C  1    N 
C  2    N 

私が達成しようとしている最終的な結果は、次のとおりです。 私はちょうどされ、その行の条件で1行を取得する各固有のIDについてはその

フラグが "Y"だった場合は、その行を返します。

それ以外の場合は最後の "N"行を返します。

注意すべきもう一つは、「Y」フラグは常に必ずしも私がこれまで OVER (PARTITION BY A."ID" ORDER BY A."Seq num")が、運のようなパーティションを使用してcase条件を取得しようとしてきた最後の

ではないということです。

- EDIT:

テーブルから、サンプル結果は次のようになります

id: id seq num: flag: date: 
A   4  Y  .. 
B   2  Y  .. 
C   2  N  .. 
+0

あなたがしようとした場合の条件は何が?そして、パーティションの結果を共通のテーブル式に入れてみて、そのケースを使用できるようにしましたか? – Sander

+0

サンプルテーブルから期待される出力を正確に表示できますか?私は、 "一意のID"が何を指しているかを理解するのに苦労しています。 –

+0

@TimBiegeleisen結果を追加しました – Pyrons

答えて

0

はDISTINCT IDを選択し、yourTable

1

からのフラグ 私のアプローチは、2つのUNIONを取ることですクエリ。最初のクエリでは、YesIDグループごとに1回しか表示されないと仮定すると、すべてYesレコードが選択されます。 2番目のクエリでは、IDのうちYesがないもののみを対象としています。これらのレコードでは、行番号を使用して最新のNoレコードを選択します。

WITH cte1 AS (
    SELECT id 
    FROM yourTable 
    GROUP BY id 
    HAVING SUM(CASE WHEN flag = 'Y' THEN 1 ELSE 0 END) = 0 
), 
cte2 AS (
    SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t1."id seq" DESC) rn 
    FROM yourTable t1 
    INNER JOIN cte1 t2 
     ON t1.id = t2.id 
) 
SELECT * 
FROM yourTable 
WHERE flag = 'Y' 
UNION ALL 
SELECT * 
FROM cte2 t2 
WHERE t2.rn = 1 
3

ウィンドウ節を使用するのが適切です。結果をIDで区切って(前と同じように)、Yフラグの行が最初に来るように、次にすべてのNフラグの行が降順に並べ替えられ、各IDの最初の行が選択されます。

SELECT id, id_seq_num, flag, date 
FROM (SELECT id, id_seq_num, flag, date, 
       ROW_NUMBER() OVER (PARTITION BY id 
            ORDER BY CASE flag WHEN 'Y' THEN 0 
                ELSE 1 
              END ASC, 
              date ASC) AS rk 
     FROM mytable) t 
WHERE rk = 1 
+1

これは私自身のクエリよりも良く見える+1 –

+0

@Mureinik 「Y」がIDごとに複数回表示される場合は、表示される最初の「Y」または日付順の最後の「Y」を選択しますか?最後の 'Y'を選択した場合、どのように最初の 'Y'のみを選択するように変更できますか?ありがとう – Pyrons

+0

@Pyrons 'order by'ウィンドウ節を編集するので、最初の' Y'だけが選択されます。 – Mureinik

1

ここで(非常に一般的なSQLを使用して)一つの方法です:

ここフィドルで利用可能
select t1.* 
from Table1 as t1 
where t1.id_seq_num = COALESCE( 
    (select max(id_seq_num) from Table1 as T2 where t1.id = t2.id and t2.flag = 'Y') , 
    (select max(id_seq_num) from Table1 as T3 where t1.id = t3.id and t3.flag = 'N')) 

http://sqlfiddle.com/#!9/5f7f9/6

+0

こんにちは@Turophile、どのように私はTable1の長いクエリが起こったと私はビューを使用することはできませんこれを書くだろうか? – Pyrons

+0

どのデータベースエンジンを使用していますか? – Turophile

+0

すべていいよ。助けてくれてありがとう – Pyrons

関連する問題