teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

調整

2019/09/05 09:31

投稿

yambejp
yambejp

スコア117885

answer CHANGED
@@ -105,6 +105,35 @@
105
105
  call myproc;
106
106
  ```
107
107
 
108
+ # 実際にprocedureが発行しているSQL文
109
+ 上記procedureが発行しているSQL文はこうです
110
+ ```SQL
111
+ select
112
+ t1.name as name1,
113
+ t1.price as price1,
114
+ t1.bikou as bikou1,
115
+ t2.name as name1,
116
+ t2.price as price1,
117
+ t2.bikou as bikou1,
118
+ t3.name as name1,
119
+ t3.price as price1,
120
+ t3.bikou as bikou1,
121
+ t4.name as name2,
122
+ t4.price as price2,
123
+ t4.bikou as bikou2
124
+ from
125
+ (select * from tbl as t0 where (select count(*)+1 from tbl where id=t0.id and pid<t0.pid)=1) as t1
126
+ left join
127
+ (select * from tbl as t0 where (select count(*)+1 from tbl where id=t0.id and pid<t0.pid)=2) as t2
128
+ on t1.id=t2.id
129
+ left join
130
+ (select * from tbl as t0 where (select count(*)+1 from tbl where id=t0.id and pid<t0.pid)=3) as t3
131
+ on t1.id=t3.id
132
+ left join
133
+ (select * from tbl as t0 where (select count(*)+1 from tbl where id=t0.id and pid<t0.pid)=4) as t4
134
+ on t1.id=t4.id
135
+ ```
136
+
108
137
  # 結果
109
138
  |name1|price1|bikou1|name2|price2|bikou2|name3|price3|bikou3|name4|price4|bikou4|
110
139
  |:--|--:|:--|:--|--:|:--|:--|--:|:--|:--|--:|:--|

3

調整

2019/09/05 09:31

投稿

yambejp
yambejp

スコア117885

answer CHANGED
@@ -103,4 +103,11 @@
103
103
  - procedure実行
104
104
  ```SQL
105
105
  call myproc;
106
- ```
106
+ ```
107
+
108
+ # 結果
109
+ |name1|price1|bikou1|name2|price2|bikou2|name3|price3|bikou3|name4|price4|bikou4|
110
+ |:--|--:|:--|:--|--:|:--|:--|--:|:--|:--|--:|:--|
111
+ |あか|100|aa|あお|200|bb|むらさき|600|xx|みずいろ|700|yy|
112
+ |きいろ|300|aa|みどり|400|bb|ちゃいろ|800|zz|NULL|NULL|NULL|
113
+ |おれんじ|500|aa|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|NULL|

2

procedure

2019/09/05 09:19

投稿

yambejp
yambejp

スコア117885

answer CHANGED
@@ -37,4 +37,70 @@
37
37
  on t2.id=t4.id
38
38
  ```
39
39
 
40
- これを右方向に自動的に伸ばしていきたいならプロシージャが必要になります。
40
+ これを右方向に自動的に伸ばしていきたいならプロシージャが必要になります。
41
+
42
+ # 右方向にどんどん伸ばす
43
+
44
+ - 元データ
45
+ ```SQL
46
+ create table tbl(
47
+ pid int primary key,
48
+ id int,
49
+ name varchar(10),
50
+ price int,
51
+ bikou varchar(30)
52
+ );
53
+
54
+ insert into tbl values
55
+ (1,1,'あか',100,'aa'),
56
+ (2,1,'あお',200,'bb'),
57
+ (3,2,'きいろ',300,'aa'),
58
+ (4,2,'みどり',400,'bb'),
59
+ (5,3,'おれんじ',500,'aa'),
60
+ (6,1,'むらさき',600,'xx'),
61
+ (7,1,'みずいろ',700,'yy'),
62
+ (8,2,'ちゃいろ',800,'zz');
63
+ ```
64
+
65
+ - procedure作成
66
+ ```SQL
67
+ drop procedure if exists myproc;
68
+ delimiter //
69
+ create procedure myproc()
70
+ begin
71
+ select max(cnt) into @max from (
72
+ select id,count(*) cnt from tbl group by id
73
+ ) as sub;
74
+ set @sql="select ";
75
+ set @c=1;
76
+ while @c<=@max do
77
+ if @c>1 then
78
+ set @sql=concat(@sql,",");
79
+ end if;
80
+ set @sql=concat(@sql,"t",@c,".name as name",@c,",t",@c,".price as price",@c,",t",@c,".bikou as bikou",@c);
81
+ set @c=@c+1;
82
+ end while;
83
+ set @c=1;
84
+ while @c<=@max do
85
+ if @c=1 then
86
+ set @sql=concat(@sql," from");
87
+ else
88
+ set @sql=concat(@sql," left join");
89
+ end if;
90
+ set @sql=concat(@sql,"(select * from tbl as t0 where (select count(*)+1 from tbl where id=t0.id and pid<t0.pid)=",@c,") as t",@c);
91
+ if @c>1 then
92
+ set @sql=concat(@sql," on t1.id=t",@c,".id");
93
+ end if;
94
+ set @c=@c+1;
95
+ end while;
96
+ prepare stmt from @sql;
97
+ execute stmt;
98
+ end
99
+ //
100
+ delimiter ;
101
+ ```
102
+ ※procedureは一回作成すればあとはデータが変化してもcallするだけでよいです
103
+ - procedure実行
104
+ ```SQL
105
+ call myproc;
106
+ ```

1

調整

2019/09/05 09:15

投稿

yambejp
yambejp

スコア117885

answer CHANGED
@@ -1,2 +1,40 @@
1
1
  普通にやると同じidに順位が付かないのでどちらがname1/name2なのか確定できないので
2
- 命題のような処理は不可能です。
2
+ 命題のような処理は不可能です。
3
+
4
+ # sample
5
+ 無理やりやるならこんな感じ
6
+ - 元データ
7
+ ```SQL
8
+ create table tbl(
9
+ pid int primary key,
10
+ id int,
11
+ name varchar(10),
12
+ price int,
13
+ bikou varchar(30)
14
+ );
15
+ insert into tbl values
16
+ (1,1,'あか',100,'aa'),
17
+ (2,1,'あお',200,'bb'),
18
+ (3,2,'きいろ',300,'aa'),
19
+ (4,2,'みどり',400,'bb'),
20
+ (5,3,'おれんじ',500,'aa');
21
+ ```
22
+ - 抽出
23
+ ```
24
+ select
25
+ t2.name as name1,
26
+ t2.price as price1,
27
+ t2.bikou as bikou1,
28
+ t4.name as name2,
29
+ t4.price as price2,
30
+ t4.bikou as bikou2
31
+ from (select *
32
+ from tbl as t1
33
+ where (select count(*)+1 from tbl where id=t1.id and pid<t1.pid)=1) as t2
34
+ left join (select *
35
+ from tbl as t3
36
+ where (select count(*)+1 from tbl where id=t3.id and pid<t3.pid)=2) as t4
37
+ on t2.id=t4.id
38
+ ```
39
+
40
+ これを右方向に自動的に伸ばしていきたいならプロシージャが必要になります。