MySQL - 最简单的方法来添加行和列

时间:2017-03-03 18:11:00

标签: mysql

我编写的报告包括总计列和总计行。到目前为止,我只是使用子查询分配变量,并将它们添加到总计列中。对于总计行,我刚刚执行了一个联合并重新运行查询,但约束较少。这是代码。

set @sdate = '2015-01-01';
set @edate = @sdate + interval 1 year;

select `a` as 'First Name', `aa` as 'Last Name',
    `b` as 'Field Tests', `c` as 'Field Inspections',
    `d` as 'Lab Tests', `e` as 'Lab Inspections',
    `f` as 'Total' from
(
    select a.first as 'a', a.last as 'aa',
    (select @b := count(*) from field_test b where b.inspector_id = a.id
        and b.date_time >= @sdate and b.date_time < @edate) as 'b',
    (select @c := count(*) from field_insp c where c.inspector_id = a.id
        and c.inspection_date >= @sdate and c.inspection_date < @edate) as 'c',
    (select @d := count(*) from lab_test d where d.inspector_id = a.id
        and d.date_time >= @sdate and d.date_time < @edate) as 'd',
    (select @e := count(*) from lab_insp e where e.inspector_id = a.id
        and e.inspection_date >= @sdate and e.inspection_date < @edate) as 'e',
    (select @f := @b + @c + @d + @e) as 'f'
    from inspector a
    order by `f` desc
) as t
where `f` > 0
union
select 'TOTALS', '',
    (select @n := count(*) from field_test
        where date_time >= @sdate and date_time < @edate),
    (select @o := count(*) from field_insp
        where inspection_date >= @sdate and inspection_date < @edate),
    (select @p := count(*) from lab_test
        where date_time >= @sdate and date_time < @edate),
    (select @q := count(*) from lab_insp
        where inspection_date >= @sdate and inspection_date < @edate),
    (select @n + @o + @p + @q)

有点冗长和混乱,但它产生了一个很好的报告。我最初使用连接编写它,但是我用子查询重写它,因为当时似乎是添加总计列和总计行的最简单方法。除了代码的详细程度之外,在使用较大表的类似报表上运行所有这些子查询所花费的时间有点长。

1 个答案:

答案 0 :(得分:0)

您可以使用with rollup子句的group by修饰符。为此,您需要由检查员进行分组。

这是一种方法:

select     case when id is null then 'Totals' else min(first) end as `First name`, 
           case when id is null then ''       else min(last)  end as `Last Name`,
           sum(ft) as `Field Tests`,
           sum(fi) as `Field Inspections`,
           sum(lt) as `Lab Tests`,
           sum(li) as `Lab Inspections`,
           sum(ft + fi + lt + li) as `Total`
from       inspector as insp
inner join (
            select   inspector_id, count(*) as ft, 0 as fi, 0 as lt, 0 as li 
            from     field_test
            where    date_time >= @sdate and date_time < @edate
            group by inspector_id
            union
            select   inspector_id, 0, count(*), 0, 0
            from     field_insp 
            where    inspection_date >= @sdate and inspection_date < @edate
            group by inspector_id
            union
            select   inspector_id, 0, 0, count(*), 0
            from     lab_test 
            where    date_time >= @sdate and date_time < @edate
            group by inspector_id
            union
            select   inspector_id, 0, 0, 0, count(*)
            from     lab_insp
            where    inspection_date >= @sdate and inspection_date < @edate
            group by inspector_id
           ) as cnt
         on cnt.inspector_id = id
group by   id with rollup;