41930
添付の画像は MS SQLServer上のあるテーブルの登録状況です。

青枠で囲った項目の組み合わせが、論理的なキーであり  
当該の組み合わせが 当日時点で有効か非有効かを管理するためのマスタとなっています。

本日時点の青枠の組み合わせで、VALIDが1（TRUE）になっているものだけを抽出したいのですが  
NULL値を含む項目を結合したINNER JOINが正規結果を取得できない理由から  
困っています。  
[![画像の説明をここに入力](https://i.stack.imgur.com/peJTM.png)](https://i.stack.imgur.com/peJTM.png)

期待のSELECT結果は、1.2.3.6.7.8.9ですが、下記発行では  
2.3.6.7.8.9です。

```

    SELECT A.* FROM SMD_M_FDSTRBT A 
    INNER JOIN 
    (SELECT FORMID, DSTTYPE, DPTID, ROLEID, MAX(YMDSTART) AS YMDSTART
    FROM SMD_M_FDSTRBT WHERE YMDSTART <= CONVERT(VARCHAR, GETDATE(), 112)
    GROUP BY FORMID, DSTTYPE, DPTID, ROLEID) B 
    ON B.FORMID=A.FORMID AND B.DSTTYPE=A.DSTTYPE AND B.DPTID=A.DPTID AND B.ROLEID=A.ROLEID
    AND B.YMDSTART=A.YMDSTART
    WHERE A.VALID=1 ORDER BY A.FORMID, A.DSTTYPE
    
```

ありきたりの問題ですが、どういった発行を行えば  
1行目を含め、4.5行目は含めない結果を得られるのでしょうか？
CC BY-SA 3.0
2018-02-22T11:14:36.383
41928
2018-02-22T16:08:34.420
2018-02-22T16:08:34.420
2238
25696
question
sql sql-server
NULL 値を含む項目の結合が行えない理由で、期待のSELECT結果を得られない（MSSQL）
SQLでは三値論理を採用しているため、`NULL`と`NULL`を比較しても`TRUE`とはなりません。  
ですので結合条件の`B.DPTID=A.DPTID`を

```

    B.DPTID = A.DPTID OR (B.DPTID IS NULL AND A.DPTID IS NULL)
    
```

のように場合分けする必要があります。

ですがこのような変則的結合条件は実行時の効率を落としますので、DBの設計を見直した方がよいでしょう。たとえば`NULL`の代わりに`''`を使用するなどの方法があります。
CC BY-SA 3.0
2018-02-22T11:51:13.997
41930
2018-02-22T11:51:13.997
5750
41928
answer