MySQl计数按4列分组

时间:2013-10-05 11:57:52

标签: mysql count group-by sum

基本上,这个查询返回了来自counts()

的不同值
Geographic Address(city),Office,Device type, Device unique type identifier, number case by device type
0001,1002,ORDENADOR,ORD1234,5 INCIDENCIAS
0001,1002,ORDENADOR,ORD3333,2 INCIDENCIAS
0001,1002,ORDENADOR,ORD2222,1 INCIDENCIAS
0001,1002,TECLADO,TECYYYY,2 INCIDENCIAS
0001,1002,TECLADO,TECXXXX,4 INCIDENCIAS
0001,1002,PANTALLA,PAN0000,1 INCIDENCIAS

Select 
        d.dt as 'Direccion Territorial',
        t.centro as 'Oficina',
        nombrelargo,
        if(length(p.Oficina)=3,concat('0',p.Oficina),p.Oficina) as 'Oficina2',
        p.Tipo_Disp as 'Dispositivo',
        count(p.Tipo_Disp) as 'Nº de partes/Etiqueta',
        p.Etq_Amarilla as 'Etiqueta',
        ------------   count(TOTAL INC DE ESE DISPOSITIVO) ---------------------------,
        ------------   count(TOTAL INC DE ESA OFICINA) ---------------------------

from textcentro t,dtdz d,ppp p
        where 
                t.jcentro03=d.dt and
                t.organizativo='OFIC./AGEN./DELEG.' and
                t.situacion='ABIERTO' and
                t.sociedad='0900' and
                (p.Estado != "Abierto" and p.Estado!= 'Planificado') and
                (month(p.Fecha_y_hora_de_creacion) = 8 and year(Fecha_y_hora_de_creacion)=2013) and
                t.centro=if(length(p.Oficina)=3,concat('0',p.Oficina),p.Oficina)

                GROUP BY d.dt,t.centro,p.Tipo_Disp,p.Etq_Amarilla

分组:

1 - d.dt ---->邮政编码

2 - t.centro ---->办公室代码

3 - p.Tipo_Disp ---->设备类型

4 - d.Etq_Amarilla ---->此设备的唯一标识符

表格是:

1- textcentro ---->办事处的具体信息

2 dtdz ---->辅助表找到办公室的邮政编码

3 ppp ---->我们可以找到所有案例的表

现在,我想按设备类型总计案例总数,应该是:

Postal Code,Office,Device type, Unique identifier for Device, total number of cases by unique identifier device, total number case by device type, total number case by office

0001,1002,ORDENADOR,ORD1234,5 INCIDENCIAS,8 INC,15
0001,1002,ORDENADOR,ORD3333,2 INCIDENCIAS,8 INC,15
0001,1002,ORDENADOR,ORD2222,1 INCIDENCIAS,8 INC,15
0001,1002,TECLADO,TECYYYY,2 INCIDENCIAS,6 INC,15
0001,1002,TECLADO,TECXXXX,4 INCIDENCIAS,6 INC,15
0001,1002,PANTALLA,PAN0000,1 INCIDENCIAS,1 INC,15

我正在尝试使用sums和count函数,但我没有达到它,我没有办法采取最后两列。我认为我可以尝试通过列中的子查询获取此数字,但性能会下降太多。

这个例子就是这个......但即使我完成了查询,我也要等待大约12-13分钟。

Select 
        d.dt as 'Direccion Territorial',
        t.centro as 'Oficina',
        nombrelargo,
        if(length(p.Oficina)=3,concat('0',p.Oficina),p.Oficina) as 'Oficina2',
        p.Tipo_Disp as 'Dispositivo',
        count(p.Tipo_Disp) as 'Nº de partes/Etiqueta',
        p.Etq_Amarilla as 'Etiqueta',
        (Select count(*) from People_DB pp where pp.Oficina=p.Oficina and pp.Tipo_Disp=Dispositivo and (month(pp.Fecha_y_hora_de_creacion) = 8 and year(pp.Fecha_y_hora_de_creacion)=2013) and (pp.Estado != "Abierto" and pp.Estado!= 'Planificado') )

from textcentro t,dtdz d,ppp p
        where 
                t.jcentro03=d.dt and
                t.organizativo='OFIC./AGEN./DELEG.' and
                t.situacion='ABIERTO' and
                t.sociedad='0900' and
                (p.Estado != "Abierto" and p.Estado!= 'Planificado') and
                (month(p.Fecha_y_hora_de_creacion) = 8 and year(Fecha_y_hora_de_creacion)=2013) and
                t.centro=if(length(p.Oficina)=3,concat('0',p.Oficina),p.Oficina)

                GROUP BY d.dt,t.centro,p.Tipo_Disp,p.Etq_Amarilla

抱歉我的英文不好,也许这篇文章难以理解

1 个答案:

答案 0 :(得分:1)

我可以提出一些建议:

首先,您选择的表格如下:

 from textcentro t,dtdz d,ppp p

为了清楚起见,我建议您使用明确的JOIN语句。例如

 FROM textcentro AS t
 JOIN dtdx       AS d      ON t.jcentro03=d.dt
 JOIN ppp        AS p      ON  XXXXXXXXX

例如,您可能希望使用LEFT JOIN,其中dtdx中可能没有相应的行与textcentro中的行一起使用。

无法从您的示例查询中判断<{1}}对ppp ON的约束是什么。我在上面的代码中显示了JOIN。我认为你的情况是这样的:

XXXXXXXXX

但这是一个令人讨厌的计算表达式,因此非常慢。看起来你的t.centro是一个包含带前导零的整数的char列,你的p.Oficina是相同的,但没有前导零。不要将前导零添加到p.Oficina,而是尝试从t.centro列中删除它。

 t.centro=if(length(p.Oficina)=3,concat('0',p.Oficina),p.Oficina)

请记住,如果没有简单的 CAST(t.centro AS INTEGER) = p.Oficina 约束,就会出现组合爆炸:m次n行。这会使事情变得缓慢而且可能是错误的。

因此,您的表格选择变为:

JOIN

第二次,您的日期/时间搜索表达式不是为了速度而构建的。试试这个:

 FROM textcentro AS t
 JOIN dtdx       AS d      ON t.jcentro03=d.dt
 JOIN ppp        AS p      ON CAST(t.centro AS INTEGER) = p.Oficina

如果您的 p.Fecha_y_hora_de_creacion >= '2013-08-01' AND p.Fecha_y_hora_de_creacion < '2013-08-01' + INTERVAL 1 MONTH 列上有索引,则会允许对该列进行范围扫描搜索。

第三次p.Fecha...列表中的此项目会导致性能下降。

SELECT

将其重构为JOIN列表中的虚拟表,如下所示。

(Select count(*) 
   from People_DB pp 
  where pp.Oficina=p.Oficina 
    and pp.Tipo_Disp=Dispositivo
    and (month(pp.Fecha_y_hora_de_creacion) = 8 
    and year(pp.Fecha_y_hora_de_creacion)=2013) 
    and (pp.Estado != "Abierto" and pp.Estado!= 'Planificado') )

所以,这是你最后的表格列表。

 (SELECT COUNT(*) AS NumPersonas,
         Oficina,
         Tipo_Disp
    FROM People_DB
   WHERE Fecha_y_hora_de_creacion >= '2013-08-01'
     AND Fecha_y_hora_de_creacion <  '2013-08-01' + INTERVAL 1 MONTH
     AND Estado != 'Abierto'
     AND Estado != 'Planificado 
   GROUP BY Oficina, Tipo_Disp
 ) AS pp_summary ON (    pp_summary.Oficina=p.Oficina
                     AND pp_summary.Tipo_Disp=Dispositivo)

这些表中有三个是“物理”表,第四个是“虚拟”表,构造为名为People_DB的物理表的摘要。

您可以加入

 FROM textcentro AS t
 JOIN dtdx       AS d      ON t.jcentro03=d.dt
 JOIN ppp        AS p      ON CAST(t.centro AS INTEGER) = p.Oficina
 JOIN  (
         SELECT COUNT(*) AS NumPersonas,
                Oficina,
                Tipo_Disp
           FROM People_DB
          WHERE Fecha_y_hora_de_creacion >= '2013-08-01'
            AND Fecha_y_hora_de_creacion <  '2013-08-01' + INTERVAL 1 MONTH
            AND Estado != 'Abierto'
            AND Estado != 'Planificado 
       GROUP BY Oficina, Tipo_Disp
 ) AS pp_summary ON (    pp_summary.Oficina=p.Oficina
                     AND pp_summary.Tipo_Disp=Dispositivo)