如果 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;

Demo fiddle

@FaNo_FN @ysth

我使用您发布的 fiddle 和您的评论设法修复了它。

我在两个查询之间添加了以下代码以检查是否设置了变量。

SET @sql := IF(@sql IS NULL,'',@sql);

我还在 GROUP_CONCAT 之前添加了第二个 CONCAT() 以添加 ',' 分隔符。

这是link到fiddle

我会让你的 GROUP_CONCATSEPARATOR '' 并用 ',' 开始你的第一个 CONCAT( args,并删除 SELECT respondents_id 之后的逗号。但是你的一些其他语法从视觉上看并不正确。