mysql动态数据透视表组

时间:2019-11-10 09:11:05

标签: mysql sql pivot-table

我正在从某些表进行动态数据透视:

select 
spec.id, 
'Spec1', 
(if(DATE_FORMAT(schedule.data,'%Y-%m-%d') = '2019-11-12', DATE_FORMAT(data,'%H:%i'),0)) as "12-11-2019",
(if(DATE_FORMAT(schedule.data,'%Y-%m-%d') = '2019-11-14', DATE_FORMAT(data,'%H:%i'),0)) as "14-11-2019",
(if(DATE_FORMAT(schedule.data,'%Y-%m-%d') = '2019-11-19', DATE_FORMAT(data,'%H:%i'),0)) as "19-11-2019"
from service_spec inner join spec on spec.id = service_spec.spec_id
     left join schedule on service_spec.spec_id = schedule.spec_id 
     where spec.id = 506
     group by schedule.data
     order by spec.name

这是查询返回的结果

id  Spec1   12.11.2019  14.11.2019  19.11.2019
508 Spec1   10:00           0           0
508 Spec1   10:30           0           0
508 Spec1   11:00           0           0
508 Spec1   11:30           0           0
508 Spec1   12:00           0           0
508 Spec1   0               0           10:00
508 Spec1   0               0           10:30
508 Spec1   0               0           11:00
508 Spec1   0               0           11:30
508 Spec1   0               0           12:00

这是我的期望:

id  Spec1   12.11.2019  14.11.2019  19.11.2019
508 Spec1   10:00       0           10:00
508 Spec1   10:30       0           10:30
508 Spec1   11:00       0           11:00
508 Spec1   11:30       0           11:30
508 Spec1   12:00       0           12:00

我该怎么做?

2 个答案:

答案 0 :(得分:0)

请使用以下查询

当每天最多输入10个且每天输入应匹配所有日期时,此功能将起作用。

select
    id,
    name,
    substring_index(substring_index(col1, ',', n), ',', -1) as '12-11-2019',
    substring_index(substring_index(col2, ',', n), ',', -1) as '14-11-2019',
    substring_index(substring_index(col3, ',', n), ',', -1) as '19-11-2019',
    n
from
    (select 
        spec.id, 
        `name`, 
        group_concat(distinct if(left(schedule.data,10) = '2019-11-12', DATE_FORMAT(schedule.data,'%H:%i'),null)) as col1,
        group_concat(distinct if(left(schedule.data,10) = '2019-11-14', DATE_FORMAT(schedule.data,'%H:%i'),null)) as col2,
        group_concat(distinct if(left(schedule.data,10) = '2019-11-19', DATE_FORMAT(schedule.data,'%H:%i'),null)) as col3
    from 
        service_spec inner join spec on spec.id = service_spec.spec_id
        left join schedule on service_spec.spec_id = schedule.spec_id 
    where 
        spec.id = 506) as main
    join (SELECT @row := @row + 1 as n 
        FROM (select 0 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) t 
        join (SELECT @row:=0) r ) as s_no 
        on char_length(col1) - char_length(replace(col1, ',', '')) >= n - 1;

输出:

 id | name  | 12-11-2019 | 14-11-2019 | 19-11-2019 |  n
--: | :---- | :--------- | :--------- | :--------- | -:
506 | Spec1 | 18:00      | 18:00      | 18:00      |  1
506 | Spec1 | 18:30      | 18:30      | 18:30      |  2
506 | Spec1 | 19:00      | 19:00      | 19:00      |  3
506 | Spec1 | 19:30      | 19:30      | 19:30      |  4
506 | Spec1 | 20:00      | 20:00      | 20:00      |  5
506 | Spec1 | 20:30      | 20:30      | 20:30      |  6

db <>提琴here

答案 1 :(得分:0)

这有点棘手。您需要条件聚合,但没有相应的列。

您可以使用row_number()创建一个:

select sc_id, 'Spec1', 
       max(case when date(sc_data) = '2019-11-12'
                then date_format(sc_data, '%H:%i')
           end) as "12-11-2019",
       max(case when date(sc_data) = '2019-11-14'
                then date_format(sc_data, '%H:%i')
           end) as "14-11-2019",
       max(case when date(sc_data) = '2019-11-19'
                then date_format(sc_data, '%H:%i')
           end) as "19-11-2019"
from (select s.id, sc.data as sc_data,
             row_number() over (partition by date(sc.data) order by sc_data) as seqnum
      from service_spec ss inner join
           spec s
           on s.id = ss.spec_id left join
           schedule sc
           on ss.spec_id = sc.spec_id 
      where s.id = 506 and
            date(sc.data) in ('2019-11-12', '2019-11-14', '2019-11-19')
     ) s
group by seqnum
order by seqnum;

在8.0之前的MySQL版本中,您可以对变量执行类似的操作。