MW211 EXIT

devlog
MSSQL/CTEで主キー条件不要だっけ問題
2019年03月14日
┌──────────────────────────────────────┐
│WITH [表1]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表0]                                                     │
│     ),                                                                     │
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表1]                                                     │
│     ),                                                                     │
│     [表3]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表2]                                                     │
│     )                                                                      │
└──────────────────────────────────────┘
例えば、CTEをつなげていくと、ふと、「主キーの結合条件っていらなかったっけ」って
不安になることがある
CROSS JOINが繰り返される想定外のレコードができてるんではという不安だ
┌──────────────────────────────────────┐
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [表1].[キー],                                               │
│                [表1].[バリュー]                                            │
│             FROM [表1]                                                     │
│                 INNER JOIN [表0]                                           │
│                   ON [表0].[キー] = [表1].[キー]                           │
│     ),                                                                     │
└──────────────────────────────────────┘
とかしなくていいのかなという不安だ

でも、これは不要
だって、展開すると以下のように自分で自分に結合している訳だから
(「[表0].[キー] = [表1].[キー]」は実質「[表0].[キー] = [表0].[キー]」だ)
こんなものは要らないということになる
┌──────────────────────────────────────┐
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [表1].[キー],                                               │
│                [表1].[バリュー]                                            │
│             FROM (                                                         │
│                 SELECT [キー],                                             │
│                        [バリュー]                                          │
│                     FROM [表0]                                             │
│             ) AS [表1]                                                     │
│                 INNER JOIN [表0]                                           │
│                   ON [表0].[キー] = [表1].[キー]                           │
│     ),                                                                     │
└──────────────────────────────────────┘

ま、あっても悪さしないけど(以下実験例([表0]の内容がそのまま返る(増殖しない)))
┌──────────────────────────────────────┐
│WITH [表1]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM (                                                         │
│                 VALUES (1, 'A'),                                           │
│                        (2, 'B'),                                           │
│                        (3, 'C')                                            │
│             ) AS [表0]([キー],[バリュー])                                  │
│     ),                                                                     │
│     [表2]([キー],[バリュー]) AS (                                          │
│         SELECT [キー],                                                     │
│                [バリュー]                                                  │
│             FROM [表1]                                                     │
│     ),                                                                     │
│     [表3]([キー],[バリュー]) AS (                                          │
│         SELECT [表2].[キー],                                               │
│                [表2].[バリュー]                                            │
│             FROM [表2]                                                     │
│                 INNER JOIN [表1]                  --本当は不要             │
│                   ON [表1].[キー] = [表2].[キー]  --本当は不要             │
│     )                                                                      │
│SELECT *                                                                    │
│    FROM [表3];                                                             │
└──────────────────────────────────────┘
逆にいうと、気づかなくて厄介といもいえる
分類:MSSQL