

以下のような3つのテーブルがあります

order_id_1 | order_value_1  
---|---  
1 | AAA  
2 | BBB  
3 | CCC  
  
order_id_1 | order_id_2 | order_value_2  
---|---|---  
1 | a | JJJ  
1 | b | KKK  
2 | c | LLL  
2 | d | MMM  
3 | e | NNN  
  
order_id_2 | order_id_3 | order_value_3  
---|---|---  
a | A | PPP  
a | B | QQQ  
b | C | RRR  
b | D | SSS  
c | E | TTT  
d | F | UUU  
d | G | VVV  
e | H | WWW  
  
この3つをJOINさせて以下のような結果を得たいのですが、方法がわかりません

order_id_1 | order_id_2 | order_id_3 | order_value_1 | order_value_2 |
order_value_3  
---|---|---|---|---|---  
1 | a | A | AAA | JJJ | PPP  
~~1~~ NULL | ~~a~~ NULL | B | ~~AAA~~ NULL | ~~JJJ~~ NULL | QQQ  
~~1~~ NULL | b | C | ~~AAA~~ NULL | KKK | RRR  
~~1~~ NULL | ~~b~~ NULL | D | ~~AAA~~ NULL | ~~KKK~~ NULL | SSS  
2 | c | E | BBB | LLL | TTT  
~~2~~ NULL | d | F | ~~BBB~~ NULL | MMM | UUU  
~~2~~ NULL | ~~d~~ NULL | G | ~~BBB~~ NULL | ~~MMM~~ NULL | VVV  
3 | e | H | CCC | NNN | WWW  
  
OUTER JOINをすると重複レコードが出てきてしまうのですが、1つのみ値を返し、2つ目以降はNULLを返すようにしたいと考えてています  
(わかりやすいようにIDはNULLを返していませんが、ここも同様です)

この実装方法が分かる方がいれば教えていただきたいです。  
よろしくお願いいたします。


CC BY-SA 4.0
2020-12-10T13:06:28.627
72571
2020-12-11T09:12:50.127
2020-12-11T03:56:47.777
4236
43102
question
mysql sql
JOINした際に重複するレコードの1つ目のみ値を返し、2つ目以降はNULLで返したい


上の行と同じ値なら次の行の値をNULLにするというのは SQL 的考えでは邪道と思われます。いや邪道ですね。  
SQＬの抽出結果は本来出力順を考慮せず、前後の行の値を比較しないので(Order Byを除く)、プログラム側で対処すべき要件と思います。

ただし MySQL8
ならウィンドウ関数が使えるので、以下のように[lag関数](https://dev.mysql.com/doc/refman/8.0/en/window-
function-descriptions.html#function_lag)を使って前の行と同じ値ならnullを返すということもできそうです。

[code]

    select 
        case when lag(order_id_1) over w = order_id_1 then null else order_id_1 end as order_id_1,
        case when lag(order_id_2) over w = order_id_2 then null else order_id_2 end as order_id_2,
    ・・・・・
    from table1 inner join table2 ・・・
    
[/code]


CC BY-SA 4.0
2020-12-11T07:35:44.817
72586
2020-12-11T08:28:01.723
2020-12-11T08:28:01.723
19617
19617
72571
answer


きっとひらぽんさんと同じことをやっているんだとは思いますが`ROW_NUMBER()`を割り出しておいて、それが`1`か否かで分岐とか。

[code]

    SELECT
        CASE order_rank_1 WHEN 1 THEN order_id_1 END,
        CASE order_rank_2 WHEN 1 THEN order_id_2 END,
        order_id_3,
        CASE order_rank_1 WHEN 1 THEN order_value_1 END,
        CASE order_rank_2 WHEN 1 THEN order_value_2 END,
        order_value_3
    FROM (
        SELECT
            order_1.order_id_1,
            order_2.order_id_2,
            order_3.order_id_3,
            order_value_1,
            order_value_2,
            order_value_3,
            ROW_NUMBER() OVER (PARTITION BY order_1.order_id_1) AS order_rank_1,
            ROW_NUMBER() OVER (PARTITION BY order_2.order_id_2) AS order_rank_2
        FROM order_3
            LEFT OUTER JOIN order_2 ON order_3.order_id_2=order_2.order_id_2
            LEFT OUTER JOIN order_1 ON order_2.order_id_1=order_1.order_id_1
    ) AS X;
    
[/code]


CC BY-SA 4.0
2020-12-11T09:12:50.127
72590
2020-12-11T09:12:50.127
4236
72571
answer