在一些业务应用程序中,原始数据进来,我对其进行规范化和处理,并存储它们以用于报告目的。
例如原始数据:
交易(交易ID、员工1 ID、员工2 ID、员工3 ID)
归一化为
交易(交易ID)
TransactionEmployee(交易ID,员工ID)
当涉及到报告要求时,员工必须出现在一行中 - 如 TransactionReport(transaction ID, some details, employee 1 ID, employee 2 ID, employee 3 ID)
我的解决方案是使用应用程序编程语言来循环 TransactionEmployee,并构造 INSERT 语句以将报告数据放入另一个表中 - 每个交易都有 3 个员工 ID。
但我觉得用 SQL 来做会更舒服。
这通过 SQL 可行吗?
最佳答案
实现此目的的一种方法是使用用户定义的变量为每笔交易的每位员工创建一个行号,然后您可以通过应用带有 CASE 表达式的聚合函数将数据行转换为列:
select transactionid,
max(case when row = 1 then employeeid end) employee1,
max(case when row = 2 then employeeid end) employee2,
max(case when row = 3 then employeeid end) employee3
from
(
select t.transactionid,
e.employeeid,
@row:=case when @prev = t.transactionid then @row else 0 end +1 row,
@prev:=t.transactionid
from transaction t
left join transactionemployee e
on t.transactionid = e.transactionid
cross join (select @row:=0, @prev = 0) c
order by t.transactionid, e.employeeid
) d
group by transactionid
order by transactionid;
参见 SQL Fiddle with Demo .
如果您不想使用用户定义的变量,那么您可以使用类似于以下的子查询:
select transactionid,
max(case when row = 1 then employeeid end) employee1,
max(case when row = 2 then employeeid end) employee2,
max(case when row = 3 then employeeid end) employee3
from
(
select t.transactionid,
e.employeeid,
(select count(*)
from transactionemployee te
where e.transactionid = te.transactionid
and te.employeeid <= e.employeeid) row
from transaction t
left join transactionemployee e
on t.transactionid = e.transactionid
) d
group by transactionid;
关于mysql - 将行转换为列的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18092829/