1

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

我正在尝试使用 sum 和 counts 函数,但我没有达到它,我没有任何方法可以获取最后两列。我认为我可以尝试通过列中的子查询来获取这个数字,但性能会下降太多。

这个例子是这样的......但即使我完成了查询并且我等待了大约 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

对不起我的英语不好,也许这篇文章是难以理解的

4

1 回答 1

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 中的行一起使用的情况下使用。

无法从您的示例查询中看出 to ppp 的ON约束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') )

将其重构为 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)

因此,这是您的最终表格列表。

 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

在您的 SELECT 列表中。

第四,避免对 MySQLGROUP BY功能的非标准扩展,使用标准 SQL。阅读此内容以获取更多信息。

http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html

第五,为您的表添加适当的索引。

于 2013-10-05T12:48:44.237 回答