列textfield
中有逗号分隔的列表值
ID | textfield
1 | english,russian,german
2 | german,french
3 | english
4 | null
我正在尝试计算文本字段中的语言数量。默认语言是“英语”,因此如果为null,则为“英语”。正确的语言数量是4(英语,俄语,德语,法语)。
这是我的查询以尝试执行此操作:
SELECT SUM((length(`textfield`) - length(replace(`textfield`, ',', '')) + 1)) as my
FROM yourtable;
我得到的结果是6
,我不知道如何对语言进行分组。
这里是小提琴 http://sqlfiddle.com/#!9/0e532/1
期望的结果是4。如何解决?
答案 0 :(得分:1)
对于5.6版(如小提琴)
SELECT COUNT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(languages.textfield, ',', numbers.num), ',', -1)) languages_count
FROM (SELECT COALESCE(textfield, 'english') textfield
FROM yourtable) languages
JOIN (SELECT 1 num UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) numbers
ON numbers.num <= LENGTH(languages.textfield) - LENGTH(REPLACE(languages.textfield, ',', '')) + 1;
对于8.x版(如评论中所述)
SELECT COUNT(DISTINCT jsontable.value) languages_count
FROM yourtable
CROSS JOIN JSON_TABLE( CONCAT('["', REPLACE(COALESCE(textfield, 'english'), ',', '","'), '"]'),
"$[*]" COLUMNS( value VARCHAR(254) PATH "$" )
) AS jsontable;
答案 1 :(得分:1)
您的查询正在做的是计算每一行中有多少种语言,并将它们全部加在一起。您的查询不考虑重复项。由于英语在表格中显示两次,因此它被计数两次(德语也被计数),因此在您的示例中为六次。另外,另一个问题是您当前的代码将null视为真正意义,即没有值。 例如,如果您的数据库是
ID | textfield
---|----------
1 | null
您还会得到不正确的结果(更多信息请参见下文)。
这使您得到逗号分隔的语言结果,没有重复。
SELECT
GROUP_CONCAT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(textfield, ',', n.digit+1), ',', -1)) textfield
FROM
yourtable
INNER JOIN
(SELECT 0 digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6) n
ON LENGTH(REPLACE(textfield, ',', '')) <= LENGTH(textfield)-n.digit;
此查询可以用作subquery,以指示您在问题提示中尝试执行的操作。换句话说,您无需提供length('textfield') ...
,而是可以通过此查询提供结果列名称
不应在数据库级别IMHO上实现此逻辑。如果您想继续考虑null
条目为英文,那很好。缺点是我之前为您提供的示例。当您有一个查询可解决数据库中的所有语言的查询时,如果英语不是明确所说的语言,而是一个null
值,则该查询将不会“计数” '英文(无效)。但是,每次发现语言数量时,您都不能只加1,因为英语可能已经很明确了。
建议:
- 在数据库中避免用normalizing your data的逗号分隔列表
- No value makes sense for a null field