我有一个关系数据库,我无法想到如何形成这个查询。
这是信息
表1
id name 1 Mike
表2
id table_1_id value setting 1 1 something setting1 2 1 something2 setting2 2 1 something3 setting3
目前,这是我的SQL查询
SELECT * FROM Table1
JOIN Table2 on Table2.table_1_id = Table1.id
这输出的内容是这样的
id name table_1_id value setting 1 Mike 1 something1 setting1 1 Mike 1 something2 setting2 1 Mike 1 something3 setting3
是否可以通过这种方式构建它以返回这些结果,以便将其导出为CSV文件?
id name table_1_id something1 something2 something3 1 Mike 1 setting1 setting2 setting3
答案 0 :(得分:2)
SELECT
Table1.*,
something1Table.setting AS something1,
something2Table.setting AS something2,
something3Table.setting AS something3
FROM Table1
JOIN Table2 AS something1Table ON something1Table.table_1_id = Table1.id AND something1Table.value = 'something'
JOIN Table2 AS something2Table ON something2Table.table_1_id = Table1.id AND something2Table.value = 'something2'
JOIN Table2 AS something3Table ON something3Table.table_1_id = Table1.id AND something3Table.value = 'something3'
答案 1 :(得分:1)
您需要条件聚合:
select table1.id, table1.name,
max(case when value = 'something1' then setting end) as setting1,
max(case when value = 'something2' then setting end) as setting2,
max(case when value = 'something3' then setting end) as setting3
from table1 join
table2
on table1.id = table2.id
group by table1.id, table1.name
答案 2 :(得分:1)
这种类型的数据转换称为 pivot ,但MySQL没有pivot功能。因此,您需要使用带有CASE
表达式的聚合函数来复制它。
如果您提前了解了值的数量,那么您可以对查询进行硬编码,类似于:
select t1.id,
t1.name,
max(case when t2.value = 'something' then t2.setting end) as setting1,
max(case when t2.value = 'something2' then t2.setting end) as setting2,
max(case when t2.value = 'something3' then t2.setting end) as setting3
from table1 t1
left join table2 t2
on t1.id = t2.table_1_id
group by t1.id, t1.name;
但是,如果您要将未知数量的值转换为列,则可以使用prepared statement to generate dynamic sql。
查询与此类似:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when t2.value = ''',
value,
''' then t2.setting end) AS `',
value, '`'
)
) INTO @sql
FROM table2;
SET @sql = CONCAT('SELECT t1.id,
t1.name, ', @sql, '
FROM table1 t1
left join table2 t2
on t1.id = t2.table_1_id
group by t1.id, t1.name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
两个版本的结果是:
| ID | NAME | SOMETHING | SOMETHING2 | SOMETHING3 |
---------------------------------------------------
| 1 | Mike | setting1 | setting2 | setting3 |
答案 3 :(得分:0)
GROUP_CONCAT可能有用。它并不能完全满足您的需求,因为它会将连接的值放入单个字段中。但是,根据你实际想要完成的事情,也许你可以解决这个问题。 GROUP_CONCAT的优点是它可以处理每个table1行的任意数量的table2行,而上面的条件聚合有三个条目(这可能是你想要的)。
SELECT table1.*,
GROUP_CONCAT(value) AS value_group,
GROUP_CONCAT(setting) AS setting_group
FROM table1
INNER JOIN table2
ON table2.table_1_id = table1.id
返回
id,person,value_group,setting_group
1,Mike,"something1,something2,something3","setting1,setting2,setting3"