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

MySQL-添加总计行和列的最简单方法,mysql,Mysql,我编写的报告包括总计列和总计行。到目前为止,我只是使用子查询分配了变量,并将它们添加到totals列中。对于totals行,我刚刚执行了一个并集并重新运行了查询,但约束较少。这是密码 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 In

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

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)
有点冗长和混乱,但它生成了一个很好的报告。我最初是用连接编写的,但我用子查询重写了它,因为当时它似乎是添加总计列和总计行的最简单方法。除了代码冗长之外,在处理较大表的类似报表上运行所有这些子查询所需的时间有点长。

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

以下是一种方法:

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;
可以使用GROUPBY子句的WITHROLLUP修饰符。为此,您需要由检查员进行分组

以下是一种方法:

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;