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

```

    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    
    
```

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

```

    22  19980127    0   0   NULL    
    22  19980127    1   0   NULL
    22  19980428    0   0   NULL
    22  19980428    1   0   NULL
    
```

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

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

再度書き直したので検討よろしくお願いします。
CC BY-SA 3.0
2017-01-19T06:31:31.753
31966
2017-01-19T11:17:03.140
2017-01-19T07:46:32.843
9566
19310
question
sql
SQL 重複するレコードを抽出したい
副問い合わせに`HAVING`句を使えばいいのでは。

```

    SELECT *
      FROM tableA
     WHERE DATE IN
    (
        SELECT DATE
          FROM tableA
         GROUP BY DATE
        HAVING COUNT(*) > 1
    )
    
```

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

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

# 追記

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

```

    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
    )
    
```

この方式は`cte`の条件が複雑である場合にコードが簡潔になります。今回は2個なので二か所に記述したほうが短くなりますが。
CC BY-SA 3.0
2017-01-19T06:39:29.957
31967
2017-01-19T08:53:00.533
2020-06-17T08:14:45.997
-1
5750
31966
answer
pgrhoさんのSQLをベースにして、WHERE句に抽出条件を追記すれば対応できると思います。  
副問い合わせで`19980127`と`19980428`を取得して、外側の主問い合わせでも同様に抽出条件を指定します。

```

    SELECT *
      FROM tableA
     WHERE DATE IN
    (
        SELECT DATE
          FROM tableA
         WHERE cal2 is null
           AND DAI in (0, 1)
         GROUP BY DATE
        HAVING COUNT(*) > 1
    )
       AND cal2 is null
       AND DAI in (0, 1)
    
```
CC BY-SA 3.0
2017-01-19T08:22:50.047
31976
2017-01-19T08:22:50.047
9820
31966
answer
window関数の使えるRDBMS(PostgreSQLなど)なら、

```

    SELECT
      id, date, dai, col1, cal2
    FROM (
      SELECT
        *,
        COUNT(*) OVER (PARTITION BY date) AS dup_count
      FROM
        table1 T1
      WHERE
        cal2 IS NULL
      AND
        dai IN (0, 1)
    ) AS T1
    WHERE
      dup_count >= 2
    ;
    
```

とすることで、サブクエリを記述せずに済みます  
計算途中の状態をSELECTで確認できるので、ロジックを簡潔に保ちやすいです
CC BY-SA 3.0
2017-01-19T11:17:03.140
31984
2017-01-19T11:17:03.140
9796
31966
answer