[英]What is the workaround if group_concat doesn't return a value
I have written a query which transforms a couple of rows based on a condition into columns.我编写了一个查询,它根据条件将几行转换为列。
However, there are cases where no row meets the condition but I want to return some results.但是,有些情况下没有行满足条件但我想返回一些结果。
Below is a sample of the table and the results I am looking for.下面是表格示例和我正在寻找的结果。
Source table:来源表:
id ![]() |
respondent_id![]() |
demographic![]() |
question![]() |
answer![]() |
---|---|---|---|---|
1 ![]() |
1 ![]() |
checked![]() |
Age![]() |
30 ![]() |
2 ![]() |
1 ![]() |
null![]() |
education![]() |
masters![]() |
3 ![]() |
1 ![]() |
checked![]() |
height![]() |
1.8m ![]() |
4 ![]() |
1 ![]() |
null![]() |
income![]() |
$1 ![]() |
5 ![]() |
1 ![]() |
null![]() |
address![]() |
ISS![]() |
6 ![]() |
1 ![]() |
null![]() |
talent![]() |
dancing![]() |
7 ![]() |
2 ![]() |
checked![]() |
Age![]() |
20 ![]() |
8 ![]() |
2 ![]() |
null![]() |
education![]() |
high school![]() |
9 ![]() |
2 ![]() |
checked![]() |
height![]() |
4m ![]() |
10 ![]() |
2 ![]() |
null![]() |
income![]() |
$3.2 ![]() |
11 ![]() |
2 ![]() |
null![]() |
address![]() |
High sea![]() |
12 ![]() |
2 ![]() |
null![]() |
talent![]() |
singing![]() |
Sample results after transformation:转换后的示例结果:
id ![]() |
respondent_id![]() |
Age![]() |
height![]() |
question![]() |
answer![]() |
---|---|---|---|---|---|
2 ![]() |
1 ![]() |
30 ![]() |
1.8m ![]() |
education![]() |
masters![]() |
4 ![]() |
1 ![]() |
30 ![]() |
1.8m ![]() |
income![]() |
$1 ![]() |
5 ![]() |
1 ![]() |
30 ![]() |
1.8m ![]() |
address![]() |
ISS![]() |
6 ![]() |
1 ![]() |
30 ![]() |
1.8m ![]() |
talent![]() |
dancing![]() |
8 ![]() |
2 ![]() |
20 ![]() |
4m ![]() |
education![]() |
high school![]() |
10 ![]() |
2 ![]() |
20 ![]() |
4m ![]() |
income![]() |
$3.2 ![]() |
11 ![]() |
2 ![]() |
20 ![]() |
4m ![]() |
address![]() |
High sea![]() |
12 ![]() |
2 ![]() |
20 ![]() |
4m ![]() |
talent![]() |
singing![]() |
Current MySQL statement:当前 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;
To clarify, the above query works when there are rows that are "checked" for the demographic column, however when there are no "checked" cells, the whole query fails.澄清一下,当人口统计列有“已检查”的行时,上述查询有效,但是当没有“已检查”单元格时,整个查询将失败。
So I would like a query that works under all conditions, whether there are demographic rows or not.所以我想要一个在所有条件下都有效的查询,无论是否有人口统计行。
If there are no demographic rows, the query is supposed to return the data without the new columns如果没有人口统计行,则查询应该返回没有新列的数据
I'm a little confused on why you are using dynamic SQL.我对您为什么使用动态 SQL 感到有些困惑。 Window functions seems to do what you want:
窗口函数似乎可以满足您的需求:
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;
I suppose you could use this as a template if you don't know the "checked" columns.如果您不知道“已检查”列,我想您可以将其用作模板。
I think your goal is to generate a query like this:我认为您的目标是生成这样的查询:
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;
However, your current syntax is generating a query like this:但是,您当前的语法正在生成这样的查询:
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;
There are no parentheses ()
wrapped around the SELECT ..
correlated subqueries which will return the following error SELECT ..
相关子查询周围没有括号()
将返回以下错误
Error 1064: You have an error in your SQL syntax;
错误 1064:您的 SQL 语法有错误; 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
检查与您的 MySQL 服务器版本相对应的手册,以在第 2 行的“SELECT l.answer FROM source_table l where l.respondent_id = a.respondent_id AND”附近使用正确的语法
You need to modify your syntax as following:你需要修改你的语法如下:
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 @FaNo_FN @ysth
I managed to fix it using the fiddle you had posted and your comments.我设法使用您发布的小提琴和您的评论来修复它。
I added the following code between the 2 queries to check if the variable is set.我在 2 个查询之间添加了以下代码以检查是否设置了变量。
SET @sql := IF(@sql IS NULL,'',@sql);
I also added a second CONCAT()
before the GROUP_CONCAT
to add a ',' separator.我还在
GROUP_CONCAT
之前添加了第二个CONCAT()
以添加一个“,”分隔符。
我会让你的GROUP_CONCAT
有SEPARATOR ''
并开始你的第一个CONCAT(
带有','
args ,并在SELECT respondents_id
之后删除逗号。但是你的一些其他语法从视觉检查中看起来并不正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.