好的,我还是sql的初学者,还不能解决这个问题。 我有四张桌子:公司,人员,细节,person_details。
companies:
id, compname
(1, ACME),
(2, ACME Group), ...
persons:
id, name, lastname, company id
(1, donald, duck, 1),
(2, lucky, luke, 1),
(3, mickey, mouse, 2)
details:
id, description
(1, 'weight'),
(2, 'height'),
(3, 'haircolor'), ...
person_details:
id, persons id, details id, value
(1, 1, 1, 70),
(2, 1, 3, 'red'),
(3, 2, 1, 90),
(4, 3, 2, 180)
如您所见,并非所有人都拥有所有细节,可用细节列表也是可变的。
现在,对于给定的人员ID和详细信息ID,我想获得包含以下内容的行:公司名称和ID,人名和姓氏,详细名称以及所提供数组中每个详细信息的值。 假设人(1,2),细节(1,3)应该导致:
companies.id, companies.name, name, lastname, details.description, person_details.value,...
1, ACME, donald, duck, 'weight', 70, 'haircolor', 'red'
2, ACEM, lucky, luke, 'weight', 90, 'haircolor', null
请帮助......
答案 0 :(得分:1)
根据您的描述,您似乎想要转移数据,但遗憾的是MySQL没有 pivot 功能,因此您需要使用聚合函数复制它使用CASE
声明。
如果您提前了解说明值,则可以将查询硬编码为以下内容:
select c.id,
c.compname,
p.name,
p.lastname,
max(case when d.description = 'weight' then pd.value end) weight,
max(case when d.description = 'haircolor' then pd.value end) haircolor,
max(case when d.description = 'height' then pd.value end) height
from companies c
left join persons p
on c.id = p.`company id`
left join person_details pd
on p.id = pd.`persons id`
left join details d
on pd.`details id` = d.id
-- where p.id in (1, 2)
group by c.id, c.compname, p.name, p.lastname
如果您的数值未知,那么您可以使用与此类似的prepared statement to generate this dynamically:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(CASE WHEN d.description = ''',
description,
''' then pd.value end) AS ',
description
)
) INTO @sql
FROM details;
SET @sql = CONCAT('SELECT c.id,
c.compname,
p.name,
p.lastname, ', @sql, '
from companies c
left join persons p
on c.id = p.`company id`
left join person_details pd
on p.id = pd.`persons id`
left join details d
on pd.`details id` = d.id
-- where p.id in (1, 2)
group by c.id, c.compname, p.name, p.lastname');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
两个版本都会生成结果:
| ID | COMPNAME | NAME | LASTNAME | WEIGHT | HEIGHT | HAIRCOLOR |
---------------------------------------------------------------------
| 1 | ACME | donald | duck | 70 | (null) | red |
| 1 | ACME | lucky | luke | 90 | (null) | (null) |
| 2 | ACME Group | mickey | mouse | (null) | 180 | (null) |