我有桌子:
id | room_type | room_size
1 | a;b;c | 5;7;12
2 | b;c;d;f | 8;2;4
3 | b;c;d;f;g;h | 6;4;5;6;7;2;9
我想要这样的输出:
id | name | room_size
1 | a | 5
1 | b | 7
1 | c | 12
2 | b | 8
2 | c | 2
2 | d | 4
2 | f | NULL
3 | b | 6
3 | c | 4
3 | d | 5
3 | f | 6
3 | g | 7
3 | h | 2
注意:在(id)2中,room_size计数减1。在(id)3中,room_size增大1
答案 0 :(得分:1)
不存储逗号分隔的值列表。 (这并不意味着使用分号代替逗号。)
SQL反模式:避免数据库编程的陷阱 – Bill Karwin,第2章
可在亚马逊和其他优质书商处购买。
https://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers/dp/1934356557
对于有限数量的值,我们可以将其拆分为单独的行
(用表格替换内联视图t
)
SELECT t.id
, i.n
, NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT( t.room_type ,';;'),';',i.n),';',-1),'') AS room_type_n
, NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT( t.room_size ,';;'),';',i.n),';',-1),'') AS room_size_n
FROM ( SELECT 1 AS id, 'a;b;c' AS room_type, '5;7;12' AS room_size
UNION ALL SELECT 2,'b;c;d;f','8;2;4'
UNION ALL SELECT 3,'b;c;d;f;g;h','6;4;5;6;7;2;9'
) t
CROSS
JOIN ( SELECT 1 AS n
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
) i
HAVING NOT ( room_type_n <=> NULL )
ORDER BY t.id, i.n
返回:
id n room_type_n room_size_n
--- --- ----------- -----------
1 1 a 5
1 2 b 7
1 3 c 12
2 1 b 8
2 2 c 2
2 3 d 4
2 4 f (NULL)
3 1 b 6
3 2 c 4
3 3 d 5
3 4 f 6
3 5 g 7
3 6 h 2
内联视图i
应该扩展到我们希望提取的有限的最大数量的值:UNION ALL SELECT 10 UNION ALL SELECT 11 ...
。