5478


## ■ 現状SQL

[code]

    SELECT Y.id, Y.hoge, Y.piyo
    FROM (
    SELECT A.id, A.hoge, A.piyo
    FROM A
    UNION ALL 
    SELECT B.a_id, "", B.piyo
    FROM B
    )Y
    
[/code]

## ■ 現状取得結果

[code]

    id　hoge　piyo
    
[/code]

## ■ 希望取得結果

[code]

    increment_id　id　hoge　piyo
    
[/code]

## ■ やりたいこと

  * `UNION ALL` する際、結果に `increment_id` カラムを新たに追加したい
  * `increment_id` カラム … レコード順に+1

## ■ 背景

  * 後で `GROUP_CONCAT` する際、使用したいので


CC BY-SA 3.0
2015-01-28T02:14:48.953
5475
2018-08-29T08:28:11.050
2015-01-28T03:15:42.610
4978
7886
question
mysql sql
MySQL で UNION ALL の結果に、インクリメントする ID カラムを追加したい


stackoverflow.com の方に
[それっぽい回答](https://stackoverflow.com/questions/11094466/generate-serial-number-
in-mysql-query/11096550#11096550) がありました。

[code]

    SELECT
      @id:=@id+1 increment_id,
      Y.id,
      Y.hoge,
      Y.piyo
    FROM 
      (select @id:=0) as id,
      (
        SELECT A.id, A.hoge, A.piyo FROM A
        UNION ALL
        SELECT B.a_id, "", B.piyo FROM B
      ) Y;
    
[/code]

([実行結果](http://www.sqlfiddle.com/#!2/e50a3/1))


CC BY-SA 3.0
2015-01-28T02:35:51.150
5478
2015-01-28T05:40:53.397
2017-05-23T12:38:55.250
-1
2992
5475
answer


ohgaさんが投稿されてる  
ユーザ変数を使う方法ですが

MySQLのマニュアルと  
OracleACEのAketiJyuuzouさんとyoku0825さんと  
日本オラクルの木村明治さんによると  
MySQLのユーザ変数は評価順序が未定義です。  
<http://qiita.com/AketiJyuuzou/items/cced9b70cc714b382d98>

なので、結果が保証されません。

具体的には、  
(select @id:=0)  
が一番最初に評価されることが保証されないので、  
最終的な結果の連番は、  
初回実行時は、nullが発生する可能性がありますし、  
2回目以降は、歯抜けや重複が発生する可能性があります。


CC BY-SA 3.0
2016-04-27T01:30:23.563
24373
2016-04-27T03:47:25.953
2020-06-17T08:14:45.997
-1
15293
5475
answer


rouさんの

> 歯抜けや重複は実際には起きないのではないでしょうか。

に対する返信です。  
コメントで書こうとしたのですが、コメントって改行できないんですね。

起きるとしたら、こんなシナリオですか  
もちろん他のシナリオもたくさんあるはずです。

MySQLのバグレポートで探せば、  
バグではありません。と一蹴されてる例があるかもしれません。

[code]

    １ インラインビュー(select ＠id:=0)の行数は1行だと分かった。
       ＠id:=0という、As指定のない無名列は、特に上位で使われてないようだ。
       (ユーザ変数@idがあるけど、先に評価しなきゃいけない仕様でないし・・・)
       次の２の処理と３の処理は、CPUが多いし、パラレルで処理しよう
    ２ クロスジョインしよう
    ３ ＠id:=0を評価しよう
    
[/code]

要するに、クロスジョインにおいて、(select ＠id:=0)の行数は評価するけど  
select句は、後回しに評価した場合です。


CC BY-SA 3.0
2016-04-27T04:21:12.550
24380
2016-04-28T01:37:23.560
2016-04-28T01:37:23.560
15293
15293
5475
answer


MySQL 8.0 以上で、 window 関数が導入されました。

[code]

    SELECT row_number() OVER w AS increment_id, *
    FROM tbl
    WINDOW w AS ()
    
[/code]

とすることで、今現在のデフォルトの返り値の順番に、行番号を採番することができます。


CC BY-SA 4.0
2018-08-29T08:28:11.050
47908
2018-08-29T08:28:11.050
754
5475
answer