基本上,这个查询从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

我在尝试求和和和和计数函数,但我没有达到它,我没有任何办法采取最后两列。我想我可以尝试通过列中的子查询获取这个数字,但是性能会下降太多。
例如。。。但即使我完成了查询,我也要等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

对不起,我的英语不好,也许这篇文章不懂

最佳答案

我可以提出一些建议吗:
首先,您选择的表格如下:

 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

例如,在dtdx中可能没有对应的行与textcentro中的行一起使用时,可能需要使用LEFT JOIN
我无法从您的示例查询中看出ON到ppp的JOIN约束应该是什么。我已经在上面的代码中用XXXXXXXXX显示了这一点。我想你的情况是这样的:
 t.centro=if(length(p.Oficina)=3,concat('0',p.Oficina),p.Oficina)

但这是一个很难计算的表达式,因此速度非常慢。看起来你的t.centro是一个包含前导零的整数的char列,而你的p.Oficina是相同的,但没有前导零。不要把前导零加到p.Oficina中,试着把它从t.centro列中去掉。
 CAST(t.centro AS INTEGER) = p.Oficina

记住,如果没有简单的JOIN约束,就会得到组合爆炸:m乘以n行。这会让事情变得缓慢,甚至可能出错。
因此,您选择的表变成:
 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列表中的这个项目正在扼杀性能。
(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)

所以,这是你最后一张桌子清单。
 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)

其中三个表是“物理”表,第四个是“虚拟”表,它是一个名为People_DB的物理表的摘要。
你可以包括
     pp_summary.NumPersonas

在您的选择列表中。
第四,避免MySQLGROUP BY功能的非标准扩展,使用标准SQL。阅读此以获取更多信息。
http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html
第五,向表中添加适当的索引。

关于mysql - MySQl计数按4列分组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19197525/

10-12 18:33