[英]how to optimize this sql query on mysql
SELECT Matricule, Nom, Section, Nom_Section,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pb1,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pt1,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv1,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-21' and '2016-2-20') and (t.Matricule=p.Matricule))) as pb2,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-21' and '2016-2-20') and (t.Matricule=p.Matricule))) as pt2,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-21' and '2016-2-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv2,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-2-21' and '2016-3-20') and (t.Matricule=p.Matricule))) as pb3,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-2-21' and '2016-3-20') and (t.Matricule=p.Matricule))) as pt3,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-2-21' and '2016-3-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv3,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-3-21' and '2016-4-20') and (t.Matricule=p.Matricule))) as pb4,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-3-21' and '2016-4-20') and (t.Matricule=p.Matricule))) as pt4,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-3-21' and '2016-4-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv4,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-4-21' and '2016-5-20') and (t.Matricule=p.Matricule))) as pb5,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-4-21' and '2016-5-20') and (t.Matricule=p.Matricule))) as pt5,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-4-21' and '2016-5-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv5,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-5-21' and '2016-6-20') and (t.Matricule=p.Matricule))) as pb6,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-5-21' and '2016-6-20') and (t.Matricule=p.Matricule))) as pt6,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-5-21' and '2016-6-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv6,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-6-21' and '2016-7-20') and (t.Matricule=p.Matricule))) as pb7,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-6-21' and '2016-7-20') and (t.Matricule=p.Matricule))) as pt7,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-6-21' and '2016-7-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv7,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-7-21' and '2016-8-20') and (t.Matricule=p.Matricule))) as pb8,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-7-21' and '2016-8-20') and (t.Matricule=p.Matricule))) as pt8,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-7-21' and '2016-8-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv8,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pb9,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pt9,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-5-21' and '2016-6-3') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv9,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pb10,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pt10,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv10,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pb11,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pt11,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv11,
(select sum(Presence_Badge_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pb12,
(select sum(Presence_theorique_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (t.Matricule=p.Matricule))) as pt12,
(select sum(Valeur_minutes) from presence t where ((Date_Effet BETWEEN '2016-1-1' and '2016-1-20') and (Motif in ('ABSI','CP','CMAR','CMAT','CNAI','COCH','FERI','FINP','DEPL','CODC','DELE','FORM','HSUP','MALA','VMED','ALET','RECU','ACTBAD'))and (t.Matricule=p.Matricule))) as pv12
from Presence p group by Matricule;
我已附上解释查询的图片,这是我的表格, 在此处输入图片说明
CREATE TABLE `presence` ( `id` int(10) NOT NULL AUTO_INCREMENT,
`date_effet` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`matricule` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`motif` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`nom` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`nom_section` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT
NULL,
`presence_badge` tinyblob,
`presence_badge_minutes` int(10) NOT NULL,
`presence_theorique` tinyblob,
`presence_theorique_minutes` int(10) NOT NULL,
`section` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`valeur` tinyblob,
`valeur_minutes` int(10) NOT NULL,
PRIMARY KEY (`id`,`date_effet`),
KEY `matricule_index` (`matricule`),
KEY `pres_index` (`matricule`,`nom`,`section`,`nom_section`)
) ENGINE=InnoDB AUTO_INCREMENT=673810 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (TO_DAYS(date_effet))
(PARTITION p_jan VALUES LESS THAN (736349) ENGINE = InnoDB,
PARTITION p_fev VALUES LESS THAN (736380) ENGINE = InnoDB,
PARTITION p_mar VALUES LESS THAN (736409) ENGINE = InnoDB,
PARTITION p_avr VALUES LESS THAN (736440) ENGINE = InnoDB,
PARTITION p_mai VALUES LESS THAN (736470) ENGINE = InnoDB,
PARTITION p_jui VALUES LESS THAN (736501) ENGINE = InnoDB,
PARTITION p_juil VALUES LESS THAN (736531) ENGINE = InnoDB,
PARTITION p_aou VALUES LESS THAN (736562) ENGINE = InnoDB,
PARTITION p_sep VALUES LESS THAN (736593) ENGINE = InnoDB,
PARTITION p_oct VALUES LESS THAN (736623) ENGINE = InnoDB,
PARTITION p_nov VALUES LESS THAN (736654) ENGINE = InnoDB,
PARTITION p_dec VALUES LESS THAN (736684) ENGINE = InnoDB) */
我确实在列'date_effet'上创建了一个分区范围,在矩阵上创建了两个索引,另一个在(matricule,Nom,Section,Nom_section)上建立了索引
首先,我将Date_Effet
添加到实际索引中。 (由于实际上要按日期过滤,并按Matricule, Nom, Section, Nom Section
分组,因此索引中的第一个字段。)
然后,我将通过SUM(CASE(
更改子查询,并添加一个覆盖所有数据范围的WHERE
子句。
select
Matricule, Nom, Section, Nom Section,
sum(case Presence_theorique_minutes when (Date_Effet BETWEEN '2016-1-1' and '2016-1-20') then Presence_theorique_minutes else 0 end) as PTM01,
sum(case Presence_theorique_minutes when (Date_Effet BETWEEN '2016-1-21' and '2016-2-20') then Presence_theorique_minutes else 0 end) as PTM02,
...
sum(case Valeur_minutes when (Date_Effet BETWEEN '2016-1-1' and '2016-1-20') then Valeur_minutes else 0 end) as VM01,
sum(case Valeur_minutes when (Date_Effet BETWEEN '2016-1-21' and '2016-2-20') then Valeur_minutes else 0 end) as VM02,
...
sum(case Presence_Badge_minutes when (Date_Effet BETWEEN '2016-1-1' and '2016-1-20') then Presence_Badge_minutes else 0 end) as PBM01,
sum(case Presence_Badge_minutes when (Date_Effet BETWEEN '2016-1-21' and '2016-2-20') then Presence_Badge_minutes else 0 end) as PBM02,
from
Presence use index(Date_Effet, Matricule, Nom, Section, Nom Section)
where
Date_Effet BETWEEN 'MIN_DATE' and 'MAX_DATE'
group by
Matricule, Nom, Section, Nom Section;
在这种情况下,由于日期范围(20到20),我将在表中添加一个新字段。 类似于analysis_period
。 将此字段构建为:[YEAR + TEORIC MONTH]
+------------+-----------------+
| date | analysis_period |
+------------+-----------------+
| 2016-01-11 | 201601 |
+------------+-----------------+
| 2016-01-21 | 201602 |
+------------+-----------------+
| 2016-02-01 | 201602 |
+------------+-----------------+
| 2016-02-25 | 201603 |
+------------+-----------------+
然后,您可以使用单个SELECT
轻松按此字段分组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.