33018


次のような2つのテーブルがあります。(SQL Server 2012)

●ryoko_data（旅行データ）

[code]

    （旅行NO）       （出発地ID）               (目的地ID)  
    ryoko_no(int)   syuppatuti_id(nvarchar)   mokutekiti_id(nvarchar)
    1               1                         2
    2               3                         1
    3               2                         1
    4               1                         3
    5               2                         3
    
[/code]

●ini_file_tekina_table (この問題に出会ったときの対象のテーブルがEAVだったので、このテーブルがEAVであることをご了承ください)

[code]

    category(nvarchar)   section(nvarchar)   item(nvarchar)
    ユーザー名            3                   一郎
    ユーザー名            2                   花子
    ユーザー名            1                   太郎
    地名                 2                   大阪
    地名                 1                   東京
    地名                 3                   名古屋
    
[/code]

次のような結果を出すことが今回の目的です。

[code]

    ryoko_no    syuppatuti_id   出発地    mokutekiti_id  目的地
    1           1               東京     2               大阪
    2           3               名古屋   1               東京
    3           2               大阪     1               東京
    4           1               東京     3               名古屋
    5           2               大阪     3               名古屋
    
[/code]

* * *

以下のSQL文を流すと、次のようになります。

[code]

    （このSQL文をXとします）
        select ryoko_no, syuppatuti_id, item, mokutekiti_id from ryoko_data r
        left join ini_file_tekina_table i on r.syuppatuti_id = i.section where category = '地名'
        order by ryoko_no
    
        ryoko_no    syuppatuti_id   item    mokutekiti_id
        1           1               東京    2
        2           3               名古屋  1
        3           2               大阪    1
        4           1               東京    3
        5           2               大阪    3
    
[/code]

ここで、目的地も地名を出したいので、以下のSQL文を流したところ、次のようになりました。

[code]

    select ryoko_no, 
    syuppatuti_id,  
    item 出発地, 
    mokutekiti_id, 
    (select item from  ini_file_tekina_table where section=mokutekiti_id and category='地名') 目的地
     from ryoko_data r
    left join ini_file_tekina_table i  on r.syuppatuti_id = i.section   where category='地名'
    order by ryoko_no
    
    ryoko_no    syuppatuti_id   出発地    mokutekiti_id  目的地
    1           1               東京     2               大阪
    2           3               名古屋   1               東京
    3           2               大阪     1               東京
    4           1               東京     3               名古屋
    5           2               大阪     3               名古屋
    
[/code]

最初はLEFT
JOIN又はONを複数利用してどうにかできないかと思いましたが、私にはできませんでした（思いついたもののエラーになったSQL文を一番下にZとして示します）ので、上のSQL文のようになりました。  
ここで、もしかしたら副問合せを使えばLEFT JOINを使わずにできるのではないかと考え、以下のSQL文を流したところ、次のようになりました。同じ結果です。

[code]

    （このSQL文をYとします）
        select ryoko_no, 
        syuppatuti_id, 
        (select item from  ini_file_tekina_table where section=syuppatuti_id and category='地名') 出発地, 
        mokutekiti_id, 
        (select item from  ini_file_tekina_table where section=mokutekiti_id and category='地名') 目的地
         from ryoko_data r
        order by ryoko_no
    
    ryoko_no    syuppatuti_id   出発地    mokutekiti_id  目的地
    1           1               東京     2               大阪
    2           3               名古屋   1               東京
    3           2               大阪     1               東京
    4           1               東京     3               名古屋
    5           2               大阪     3               名古屋
    
[/code]

ここで質問なのですが、Yによる結果をJOINを使って（副問合せを用いずに、Xを発展させる形で）出せますか？

[code]

    エラーになったSQL文 Z
        select ryoko_no, 
        syuppatuti_id,  
        item, 
        mokutekiti_id, 
        i2.item
        (select item from  ini_file_tekina_table where section=mokutekiti_id and category='地名')
         from ryoko_data r
        left join ini_file_tekina_table i  on r.syuppatuti_id = i.section   where category='地名' 
        left join ini_file_tekina_table i2  on r.mokutekiti_id = i.section   where category='地名'
        order by ryoko_no
    
[/code]


CC BY-SA 4.0
2017-03-01T10:02:02.137
33015
2018-11-25T12:42:54.863
2018-11-25T12:42:54.863
19705
19705
question
sql sql-server
1つのテーブルの特定の1列を複数列にJOINさせる方法は？


`JOIN`の構文について誤解があるように思われます。

`SELECT`文の基本的な構造は

[code]

    SELECT 列リスト FROM テーブル[ WHERE 条件][ ORDER BY ソートキー]
    
[/code]

のようになっています。ですので副問い合わせや`UNION`を無視すれば`WHERE`句は通常1回しか出現しません。そして`JOIN`は上の _テーブル_
の部分の文法で、これは

[code]

    FROM テーブル[ (INNER|LEFT|RIGHT|FULL) JOIN テーブル ON 条件](繰り返し可)
    
[/code]

のように使用します。ですので`JOIN`時に追加の条件が指定したければ`AND`で指定するのが一般的です。

> left join ini_file_tekina_table i on r.syuppatuti_id = i.section **AND**
> category = '地名'

この方法を使うと質問のSQLは

[code]

    SELECT r.ryoko_no
         , r.syuppatuti_id
         , i1.item AS 出発地
         , r.mokutekiti_id
         , i2.item AS 目的地
      FROM ryoko_data r
      LEFT JOIN ini_file_tekina_table i1
        ON r.syuppatuti_id = i1.section
       AND i1.category='地名'
      LEFT JOIN ini_file_tekina_table i2
        ON r.mokutekiti_id = i2.section
       AND i2.category='地名'
     ORDER BY r.ryoko_no
    
[/code]

のようになります。

なお元のSQLのように`WHERE`句に条件を指定することもできますが、ここでは`LEFT
JOIN`を使用しているので`ini_file_tekina_table`に結合対象のレコードが存在しなかった場合の動作が変化します。`ON`に`category`の条件を指定した場合、対象の出発地/目的地が存在しない`ryoko_data`レコードも`SELECT`対象になりますが、`WHERE`で指定した場合は結合後のレコードに対して`category`の判定が行われますので、`ini_file_tekina_table`のレコードが存在しない組み合わせは値が`NULL`になり条件と一致しません。ですので`LEFT
JOIN`が指定されていますが、実質的に`INNER JOIN`と同一の動作になります。


CC BY-SA 3.0
2017-03-01T10:44:47.023
33018
2017-03-01T10:55:36.807
2017-03-01T10:55:36.807
5750
5750
33015
answer