如果 group_concat 没有 return 值,解决方法是什么
What is the workaround if group_concat doesn't return a value
我编写了一个查询,它根据条件将几行转换为列。
但是,有些情况下没有行满足条件但我想return一些结果。
下面是 table 的示例和我正在寻找的结果。
来源table:
id
respondent_id
人口统计
问题
回答
1
1
已检查
年龄
30
2
1
无
教育
大师
3
1
已检查
身高
1.8m
4
1
无
收入
1 美元
5
1
无
地址
国际空间站
6
1
无
天赋
跳舞
7
2
已检查
年龄
20
8
2
无
教育
高中
9
2
已检查
身高
4米
10
2
无
收入
3.2 美元
11
2
无
地址
公海
12
2
无
天赋
唱歌
转换后的示例结果:
id
respondent_id
年龄
身高
问题
回答
2
1
30
1.8m
教育
大师
4
1
30
1.8m
收入
1 美元
5
1
30
1.8m
地址
国际空间站
6
1
30
1.8m
天赋
跳舞
8
2
20
4米
教育
高中
10
2
20
4米
收入
3.2 美元
11
2
20
4米
地址
公海
12
2
20
4米
天赋
唱歌
当前 MySQL 语句:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'(SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id AND l.question = ', b.question,')
AS ',b.question
)
) INTO @sql
FROM source_table b
WHERE b.demographic IS NOT NULL;
SET @sql =
CONCAT('SELECT respondents_id,
',@sql,',
a.question , a.answer
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY id
');
PREPARE stmt FROM @sql;
EXECUTE stmt;
需要说明的是,当存在针对人口统计列“选中”的行时,上述查询有效,但是当没有“选中”单元格时,整个查询将失败。
所以我想要一个在所有条件下都有效的查询,无论是否有人口统计行。
如果没有人口统计行,查询应该return没有新列的数据
我有点不明白你为什么要使用动态 SQL。 Window 函数似乎做你想做的事:
select t.*
from (select t.*,
max(case when question = 'Age' then answer end) over (partition by respondent_id ) as age,
max(case when question = 'height' then answer end) over (partition by respondent_id ) as height
from source_table st
) t
where demographic is null;
如果您不知道“选中”列,我想您可以将其用作模板。
我认为您的目标是生成如下查询:
SELECT respondent_id, a.question , a.answer,
(SELECT l.answer
FROM source_table l
WHERE l.respondent_id = a.respondent_id AND l.question = "Age") AS Age,
(SELECT l.answer
FROM source_table l
WHERE l.respondent_id = a.respondent_id AND l.question = "height") AS height
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY respondent_id, a.question , a.answer;
但是,您当前的语法生成的查询如下:
SELECT respondents_id,
SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id
AND l.question = Age AS Age,
SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id
AND l.question = height AS height,
a.question , a.answer
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY id;
没有括号 ()
环绕 SELECT ..
相关子查询,这将 return 以下错误
Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id AND ' at line 2
您需要修改语法如下:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'(SELECT l.answer
FROM source_table l where l.respondent_id = a.respondent_id
AND l.question = "', b.question,'") AS ',b.question)
) INTO @sql
FROM source_table b
WHERE b.demographic IS NOT NULL;
SELECT @sql; /*added in between to check the current variable value. Removable.*/
SET @sql =
CONCAT('SELECT respondent_id, a.question , a.answer,
',@sql,'
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY respondent_id, a.question , a.answer
');
SELECT @sql; /*added in between to check the current variable value. Removable.*/
PREPARE stmt FROM @sql;
EXECUTE stmt;
@FaNo_FN @ysth
我使用您发布的 fiddle 和您的评论设法修复了它。
我在两个查询之间添加了以下代码以检查是否设置了变量。
SET @sql := IF(@sql IS NULL,'',@sql);
我还在 GROUP_CONCAT
之前添加了第二个 CONCAT()
以添加 ',' 分隔符。
这是link到fiddle
我会让你的 GROUP_CONCAT
有 SEPARATOR ''
并用 ','
开始你的第一个 CONCAT(
args,并删除 SELECT respondents_id
之后的逗号。但是你的一些其他语法从视觉上看并不正确。
我编写了一个查询,它根据条件将几行转换为列。
但是,有些情况下没有行满足条件但我想return一些结果。
下面是 table 的示例和我正在寻找的结果。
来源table:
id | respondent_id | 人口统计 | 问题 | 回答 |
---|---|---|---|---|
1 | 1 | 已检查 | 年龄 | 30 |
2 | 1 | 无 | 教育 | 大师 |
3 | 1 | 已检查 | 身高 | 1.8m |
4 | 1 | 无 | 收入 | 1 美元 |
5 | 1 | 无 | 地址 | 国际空间站 |
6 | 1 | 无 | 天赋 | 跳舞 |
7 | 2 | 已检查 | 年龄 | 20 |
8 | 2 | 无 | 教育 | 高中 |
9 | 2 | 已检查 | 身高 | 4米 |
10 | 2 | 无 | 收入 | 3.2 美元 |
11 | 2 | 无 | 地址 | 公海 |
12 | 2 | 无 | 天赋 | 唱歌 |
转换后的示例结果:
id | respondent_id | 年龄 | 身高 | 问题 | 回答 |
---|---|---|---|---|---|
2 | 1 | 30 | 1.8m | 教育 | 大师 |
4 | 1 | 30 | 1.8m | 收入 | 1 美元 |
5 | 1 | 30 | 1.8m | 地址 | 国际空间站 |
6 | 1 | 30 | 1.8m | 天赋 | 跳舞 |
8 | 2 | 20 | 4米 | 教育 | 高中 |
10 | 2 | 20 | 4米 | 收入 | 3.2 美元 |
11 | 2 | 20 | 4米 | 地址 | 公海 |
12 | 2 | 20 | 4米 | 天赋 | 唱歌 |
当前 MySQL 语句:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'(SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id AND l.question = ', b.question,')
AS ',b.question
)
) INTO @sql
FROM source_table b
WHERE b.demographic IS NOT NULL;
SET @sql =
CONCAT('SELECT respondents_id,
',@sql,',
a.question , a.answer
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY id
');
PREPARE stmt FROM @sql;
EXECUTE stmt;
需要说明的是,当存在针对人口统计列“选中”的行时,上述查询有效,但是当没有“选中”单元格时,整个查询将失败。
所以我想要一个在所有条件下都有效的查询,无论是否有人口统计行。
如果没有人口统计行,查询应该return没有新列的数据
我有点不明白你为什么要使用动态 SQL。 Window 函数似乎做你想做的事:
select t.*
from (select t.*,
max(case when question = 'Age' then answer end) over (partition by respondent_id ) as age,
max(case when question = 'height' then answer end) over (partition by respondent_id ) as height
from source_table st
) t
where demographic is null;
如果您不知道“选中”列,我想您可以将其用作模板。
我认为您的目标是生成如下查询:
SELECT respondent_id, a.question , a.answer,
(SELECT l.answer
FROM source_table l
WHERE l.respondent_id = a.respondent_id AND l.question = "Age") AS Age,
(SELECT l.answer
FROM source_table l
WHERE l.respondent_id = a.respondent_id AND l.question = "height") AS height
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY respondent_id, a.question , a.answer;
但是,您当前的语法生成的查询如下:
SELECT respondents_id,
SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id
AND l.question = Age AS Age,
SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id
AND l.question = height AS height,
a.question , a.answer
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY id;
没有括号 ()
环绕 SELECT ..
相关子查询,这将 return 以下错误
Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id AND ' at line 2
您需要修改语法如下:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'(SELECT l.answer
FROM source_table l where l.respondent_id = a.respondent_id
AND l.question = "', b.question,'") AS ',b.question)
) INTO @sql
FROM source_table b
WHERE b.demographic IS NOT NULL;
SELECT @sql; /*added in between to check the current variable value. Removable.*/
SET @sql =
CONCAT('SELECT respondent_id, a.question , a.answer,
',@sql,'
FROM source_table a
WHERE a.demographic IS NULL
GROUP BY respondent_id, a.question , a.answer
');
SELECT @sql; /*added in between to check the current variable value. Removable.*/
PREPARE stmt FROM @sql;
EXECUTE stmt;
@FaNo_FN @ysth
我使用您发布的 fiddle 和您的评论设法修复了它。
我在两个查询之间添加了以下代码以检查是否设置了变量。
SET @sql := IF(@sql IS NULL,'',@sql);
我还在 GROUP_CONCAT
之前添加了第二个 CONCAT()
以添加 ',' 分隔符。
这是link到fiddle
我会让你的 GROUP_CONCAT
有 SEPARATOR ''
并用 ','
开始你的第一个 CONCAT(
args,并删除 SELECT respondents_id
之后的逗号。但是你的一些其他语法从视觉上看并不正确。