【问题标题】:Separate comma separated list into query columns将逗号分隔的列表分隔为查询列
【发布时间】:2014-08-20 18:57:32
【问题描述】:

我有一个表,其中的列包含逗号分隔列表,如

ID :  List 
1  :  1,2,44,5      --row# 1
2  :  4,3,5,2,56,66 --row# 2

等等。我想编写一个选择查询,它最多有 10 列 Item1、Item2、Item3 .... Item10 并且每列都有一个来自相应逗号分隔列表的数字。

例如:ID = 1

Item1 = 1, Item2 = 2, Item3 = 44, Item4 = 55 and all other columns would be null or empty

如何用 SQL 编写?

【问题讨论】:

  • 滥用SUBSTRING_INDEX函数也可以。
  • 这个问题的两个部分......首先是解析值,其次是将它们旋转到您想要的显示中。不是最简单的问题,但答案应该已经在堆栈溢出上。并且一如既往地需要包括“为什么有人会以这种数组方式将数据保存到数据库?通过不将数组插入到数据库中的单个字段中,最容易解决问题。'
  • @Twelfth 实际上数据库已经存在了,写这样的查询是项目的要求。
  • 你可以有多少个逗号分隔的项目?
  • @JohnRuddell 10 个项目,如果超过 10 个项目,则只需获取前 10 个项目并将它们放在 Select Query 的所需列中

标签: mysql sql


【解决方案1】:

你可以这样做:

select
    substring_index(substring_index(str,',',1),',',-1)AS c1
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 1 THEN substring_index(substring_index(str,',',2),',',-1) ELSE NULL END AS c2
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 2 THEN substring_index(substring_index(str,',',3),',',-1) ELSE NULL END AS c3
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 3 THEN substring_index(substring_index(str,',',4),',',-1) ELSE NULL END AS c4
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 4 THEN substring_index(substring_index(str,',',5),',',-1) ELSE NULL END AS c5
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 5 THEN substring_index(substring_index(str,',',6),',',-1) ELSE NULL END AS c6
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 6 THEN substring_index(substring_index(str,',',7),',',-1) ELSE NULL END AS c7
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 7 THEN substring_index(substring_index(str,',',8),',',-1) ELSE NULL END AS c8
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 8 THEN substring_index(substring_index(str,',',9),',',-1) ELSE NULL END AS c9
,   CASE WHEN LENGTH(str)-LENGTH(REPLACE(str,',','')) >= 9 THEN substring_index(substring_index(str,',',10),',',-1) ELSE NULL END AS c10
from test

Demo.

表达式有两个共同部分:

  • LENGTH(str)-LENGTH(REPLACE(str,',','')) >= K - 此子表达式确定字符串是否至少有 K 分隔符
  • substring_index(substring_index(str,',',K),',',-1) - 这个子表达式删除了K-th 分隔符之后的元素

【讨论】:

  • 这就是我写答案的方式!打败我 :) 但不管 +1
【解决方案2】:

这可以通过从MySQL Split String Function 创建一个用户定义的函数引用来完成,将包含逗号分隔字符串的列作为第一个参数传递给该函数,在第二个参数中传递分隔符,在您的情况下,逗号是分隔符,在第三个参数传递你想要的位置来获取字符串

SPLIT_STR(字符串、分隔符、位置)

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');

然后你可以在下面查询你的数据

SELECT 
SPLIT_STR(List, ',', 1) item1,
SPLIT_STR(List, ',', 2) item2,
SPLIT_STR(List, ',', 3) item3,
SPLIT_STR(List, ',', 4) item4,
SPLIT_STR(List, ',', 5) item5,
SPLIT_STR(List, ',', 6) item6,
SPLIT_STR(List, ',', 7) item7,
SPLIT_STR(List, ',', 8) item8,
SPLIT_STR(List, ',', 9) item9,
SPLIT_STR(List, ',', 10) item10
FROM t

Fiddle Demo

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 2013-10-26
  • 1970-01-01
  • 2013-07-03
  • 2015-11-29
相关资源
最近更新 更多