SQL 重複するレコードを抽出したい


お世話になっております。  
いろいろと調べたのですが、なかなか期待通りの結果が出ないので質問させて頂きます。  
  
**tableA**

[code]

    ID　　　DATE　　DAI col1 cal2
    22  19970901    0   2   l7  　　　
    22  19970901    0   3   r7  　　　　
    22  19970912    0   0   NULL    
    22  19970912    0   1   R7  　　　
    22  19970912    0   2   R76 　　　
    22  19970912    0   3   l7　　　　　
    22  19971205    0   0   NULL    
    22  19971205    0   1   l7  　　　
    22  19971205    0   2   l4  　　　
    22  19971216    0   0   NULL    
    22  19971216    0   1   l7  　　　
    22  19971216    0   2   r32 　　　
    22  19980127    0   0   NULL    
    22  19980127    0   1   R1  　　　
    22  19980127    0   2   R3  　　　
    22  19980127    1   0   NULL    
    22  19980127    1   1   R1  　　
    22  19980206    0   0   NULL    
    22  19980206    0   1   R2　　　　
    22  19980206    0   2   R3　　　　
    22  19980206    0   3   R2　　　　　
    22  19980217    0   0   NULL　　　　
    22  19980217    0   1   R2　　　
    22  19980217    0   2   R3　　　
    22  19980407    0   0   NULL    
    22  19980407    0   1   L67　　　　
    22  19980407    0   2   R765    
    22  19980428    0   0   NULL    
    22  19980428    0   1   L67　　　　
    22  19980428    0   2   r7　　　　　
    22  19980428    0   3   R7　　　　　
    22  19980428    0   4   L2345   
    22  19980428    1   0   NULL    
    
[/code]

`cal2`が`null`で、`DAI`が`1`か`0`で、同じ日付のレコード期待値としては

[code]

    22  19980127    0   0   NULL    
    22  19980127    1   0   NULL
    22  19980428    0   0   NULL
    22  19980428    1   0   NULL
    
[/code]

この４件が抽出できるようにしたいです。  
ご教授の程よろしくお願いします。

回答頂いた方すみません。レコードと抽出条件が説明不足でした。

再度書き直したので検討よろしくお願いします。




副問い合わせに`HAVING`句を使えばいいのでは。

[code]

    SELECT *
      FROM tableA
     WHERE DATE IN
    (
        SELECT DATE
          FROM tableA
         GROUP BY DATE
        HAVING COUNT(*) > 1
    )
    
[/code]

上記のSQLについて解説すると、まず`WHERE DATE IN
(...)`と副問い合わせを用いることで「レコードの表示」の前に重複する`DATE`をあらかじめ検索することを考えます。

次に「重複する`DATE`の検索」ですが、これには`GROUP
BY`と`HAVING`を併用します。`HAVING`句の条件はグループ化の後に評価されるため、`COUNT(*)`は`GROUP BY
DATE`の各グループのレコード数を表します。ですので上記の副問い合わせで「重複する`DATE`」を`SELECT`することが可能です。

# 追記

`tableA`に事前に条件を追加したいということですので、payanecoさんの方法で問題ないと思いますが上のSQLを共通表式に対して使用する方法を記載しておきます。

[code]

    WITH cte
    AS
    (
        SELECT *
          FROM tableA
         WHERE DAI IN ('0', '1')
           AND cal2 IS NULL
    )
    SELECT *
      FROM cte
     WHERE DATE IN
    (
        SELECT DATE
          FROM cte
         GROUP BY DATE
        HAVING COUNT(*) > 1
    )
    
[/code]

この方式は`cte`の条件が複雑である場合にコードが簡潔になります。今回は2個なので二か所に記述したほうが短くなりますが。




副問い合わせに`HAVING`句を使えばいいのでは。

[code]

    SELECT *
      FROM tableA
     WHERE DATE IN
    (
        SELECT DATE
          FROM tableA
         GROUP BY DATE
        HAVING COUNT(*) > 1
    )
    
[/code]

上記のSQLについて解説すると、まず`WHERE DATE IN
(...)`と副問い合わせを用いることで「レコードの表示」の前に重複する`DATE`をあらかじめ検索することを考えます。

次に「重複する`DATE`の検索」ですが、これには`GROUP
BY`と`HAVING`を併用します。`HAVING`句の条件はグループ化の後に評価されるため、`COUNT(*)`は`GROUP BY
DATE`の各グループのレコード数を表します。ですので上記の副問い合わせで「重複する`DATE`」を`SELECT`することが可能です。

# 追記

`tableA`に事前に条件を追加したいということですので、payanecoさんの方法で問題ないと思いますが上のSQLを共通表式に対して使用する方法を記載しておきます。

[code]

    WITH cte
    AS
    (
        SELECT *
          FROM tableA
         WHERE DAI IN ('0', '1')
           AND cal2 IS NULL
    )
    SELECT *
      FROM cte
     WHERE DATE IN
    (
        SELECT DATE
          FROM cte
         GROUP BY DATE
        HAVING COUNT(*) > 1
    )
    
[/code]

この方式は`cte`の条件が複雑である場合にコードが簡潔になります。今回は2個なので二か所に記述したほうが短くなりますが。

