2017-07-04 111 views
2

我有三个表(pagu,realisasi和perencanaan)。我正在使用左连接。我想在某个日期之前总计一个字段,而在该日期之前和另一个字段总和。MySQL在日期之前与SUM之前加SUM并在此日期之前

我帕吉塔表:

idpagu kode komponen pagu target_kinerja tahun keterangan 
1 2217.057.056 Pengembangan Sistem Manajemen Mutu UPTP  52740000 1 2017 tes123 
2 2220.051.051 Pelatihan Peningkatan Produktivitas  4732755000 120  2017 tes123 
3 2220.052.051 Calon Wirausaha Baru yang Dilatih (RM) 12464938000  240  2017 TES123 

my pagu table

我realisasi表:

idrealisasi  idpagu kode komponen realisasi target_kinerja tgl  keterangan 
5 1 2217.057.056 Pengembangan Sistem Manajemen Mutu UPTP  52740000 1 1/14/2017 tes 
6 2 2220.051.051 Pelatihan Peningkatan Produktivitas  10000000 10 1/14/2017 tes 
7 2 2220.051.051 Pelatihan Peningkatan Produktivitas  20000000 20 2/14/2017 tes2 
8 2 2220.051.051 Pelatihan Peningkatan Produktivitas  10000000 10 3/14/2017 tes3 
9 2 2220.051.051 Pelatihan Peningkatan Produktivitas  10000000 10 6/14/2017 tes4 
10 2 2220.051.051 Pelatihan Peningkatan Produktivitas  10000000 10 1/15/2017 tes 

my realisasi table

我perencanaan表(没有记录):

idperencanaan idpagu kode komponen penarikan target_kinerja tgl  keterangan 

my perencanaan table

我的查询:

select p.idpagu,p.kode,p.komponen,p.pagu,p.target_kinerja, 
if(pr.penarikan is null,0,sum(pr.penarikan)) as perenuang, 
if(pr.target_kinerja is null,0,sum(pr.target_kinerja)) as perenfis, 
if(r.realisasi is null,0,sum(r.realisasi)) as realuang, 
if(r.target_kinerja is null,0,sum(r.target_kinerja)) as realfis, 
p.pagu-if(r.realisasi is null,0,sum(r.realisasi)) as sisauang, 
p.target_kinerja-if(r.target_kinerja is null,0,sum(r.target_kinerja)) as sisafis, 
if(sum(rr.realisasi) is null,0,sum(rr.realisasi)) as tes 
from pagu p 
left join realisasi r on p.idpagu=r.idpagu and r.tgl BETWEEN "2017-01-01" and "2017-01-15" 
left join perencanaan pr on p.idpagu=pr.idpagu and r.tgl BETWEEN "2017-01-01" and "2017-01-15" 
left join realisasi rr on p.idpagu=rr.idpagu and rr.tgl < "2017-01-15" 
group by p.idpagu,r.idpagu,rr.idpagu 

我的结果:

idpagu kode komponen pagu target_kinerja perenuang perenfis realuang realfis  sisauang sisafis  tes 
1 2217.057.056 Pengembangan Sistem Manajemen Mutu UPTP  52740000 1 0 0 52740000 1 0 0 52740000 
2 2220.051.051 Pelatihan Peningkatan Produktivitas  4732755000 120  0 0 20000000 20 4712755000 100  20000000 
3 2220.052.051 Calon Wirausaha Baru yang Dilatih (RM) 12464938000  240  0 0 0 0 12464938000  240  0 

my query

我的问题:

在当前日期“2017-01-15”之前,tes列是pagu - realuang,第二行应该是10.000.000,但是我的查询结果为20.000.000。 如何编写我的查询,以便在第二个记录中tes列为10.000.000?

我的架构:

SET FOREIGN_KEY_CHECKS=0; 

DROP TABLE IF EXISTS `pagu`; 
CREATE TABLE `pagu` (
    `idpagu` int(11) NOT NULL AUTO_INCREMENT, 
    `kode` varchar(45) NOT NULL, 
    `komponen` varchar(250) NOT NULL, 
    `pagu` bigint(20) NOT NULL, 
    `target_kinerja` int(11) NOT NULL, 
    `tahun` varchar(4) NOT NULL, 
    `keterangan` varchar(250) DEFAULT NULL, 
    PRIMARY KEY (`idpagu`) 
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; 

INSERT INTO `pagu` VALUES ('1', '2217.057.056', 'Pengembangan Sistem Manajemen Mutu UPTP', '52740000', '1', '2017', 'tes123'); 
INSERT INTO `pagu` VALUES ('2', '2220.051.051', 'Pelatihan Peningkatan Produktivitas', '4732755000', '120', '2017', 'tes123'); 
INSERT INTO `pagu` VALUES ('3', '2220.052.051', 'Calon Wirausaha Baru yang Dilatih (RM)', '12464938000', '240', '2017', 'TES123'); 

DROP TABLE IF EXISTS `perencanaan`; 
CREATE TABLE `perencanaan` (
    `idperencanaan` int(11) NOT NULL AUTO_INCREMENT, 
    `idpagu` int(11) NOT NULL, 
    `kode` varchar(45) NOT NULL, 
    `komponen` varchar(250) NOT NULL, 
    `penarikan` bigint(20) NOT NULL, 
    `target_kinerja` int(11) NOT NULL, 
    `tgl` date NOT NULL, 
    `keterangan` varchar(250) DEFAULT NULL, 
    PRIMARY KEY (`idperencanaan`), 
    KEY `fk_perencanaan_pagu1_idx` (`idpagu`), 
    CONSTRAINT `fk_perencanaan_pagu1` FOREIGN KEY (`idpagu`) REFERENCES `pagu` (`idpagu`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

DROP TABLE IF EXISTS `realisasi`; 
CREATE TABLE `realisasi` (
    `idrealisasi` int(11) NOT NULL AUTO_INCREMENT, 
    `idpagu` int(11) NOT NULL, 
    `kode` varchar(45) NOT NULL, 
    `komponen` varchar(250) NOT NULL, 
    `realisasi` bigint(20) NOT NULL, 
    `target_kinerja` int(11) NOT NULL, 
    `tgl` date NOT NULL, 
    `keterangan` varchar(250) DEFAULT NULL, 
    PRIMARY KEY (`idrealisasi`), 
    KEY `fk_perencanaan_pagu1_idx` (`idpagu`), 
    CONSTRAINT `fk_perencanaan_pagu10` FOREIGN KEY (`idpagu`) REFERENCES `pagu` (`idpagu`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; 

INSERT INTO `realisasi` VALUES ('5', '1', '2217.057.056', 'Pengembangan Sistem Manajemen Mutu UPTP', '52740000', '1', '2017-01-14', 'tes'); 
INSERT INTO `realisasi` VALUES ('6', '2', '2220.051.051', 'Pelatihan Peningkatan Produktivitas', '10000000', '10', '2017-01-14', 'tes'); 
INSERT INTO `realisasi` VALUES ('7', '2', '2220.051.051', 'Pelatihan Peningkatan Produktivitas', '20000000', '20', '2017-02-14', 'tes2'); 
INSERT INTO `realisasi` VALUES ('8', '2', '2220.051.051', 'Pelatihan Peningkatan Produktivitas', '10000000', '10', '2017-03-14', 'tes3'); 
INSERT INTO `realisasi` VALUES ('9', '2', '2220.051.051', 'Pelatihan Peningkatan Produktivitas', '10000000', '10', '2017-06-14', 'tes4'); 
INSERT INTO `realisasi` VALUES ('10', '2', '2220.051.051', 'Pelatihan Peningkatan Produktivitas', '10000000', '10', '2017-01-15', 'tes'); 
+0

感谢您的快速响应@philipxy。你是对的,并在某个日期总结。我有添加架构和代码snipet(我的表很长),因此用户可以复制粘贴它。 –

+0

感谢您的编辑。请:不要使用链接。不要使用图像。即使对于ER图,也可以在文本中给出信息。如果你的问题不是PHP/HTML/JavaScript,请不要使用片段。将代码编辑为“代码块”。 (缩进4个空格或点击“{}”。)转到sqlfiddle.com。 (没有其他语言的固定网站。)查询以显示您的表格值。运行您的查询。将sqlfiddle链接编辑到您的问题中。你*可以*还包括在代码块中使用对齐列重新格式化的sqlfiddle输出;或者可以将代码的INSERT VALUES格式化为具有对齐的列。 (对齐=人类可读。) – philipxy

+0

请不要保留旧的不清楚的文本;编辑你的问题要清楚。你所有的原文都不清楚。在我最后的评论中,我猜想两部分都是一样的。但我不知道那是什么。我也无法理解你的新描述。小步说事。另外,你仍然只是通过一个例子来描述你想要的东西。但是一个什么样的例子?试着告诉我们,当它在一张桌子上时,它说了什么。重新举例:请阅读[mcve]。你希望的*输出表是什么?也许使用一个简单/编辑的例子,只是显示你的问题/需求。 – philipxy

回答

0

从您的查询和表&列名猜(帕吉塔=天花板,realisasi =实际,perencanaan =计划),为您在天总结其实际值每天花板某些范围,那些日子的计划值,其中某些日子的实际值以及一些相关目标值,将NULL值视为0.

我假设如果上限在某个日期具有实际值,那么它在该日期具有计划价值。否则,您的查询将涉及FULL JOIN,而LEFT JOIN会错误地形成具有不同日期的行等等。所以我怀疑您缺少FK(外键)。

您的第一个LEFT JOIN会在某些日期获取每个天花板的实际值。然后,您需要天花板的任何计划值&日期。所以你失踪and r.tgl = pr.tgl。然后,您需要上限&日期的某些实际值。所以你的第三个LEFT JOIN缺少and r.tgl = rr.tgl

您正在编组&不正确地求和。如果SELECT使用聚合调用外的列,那么对于GROUPed列的每个子区域,它应该是单值的。 (GROUP BY返回GROUPED列的每个子行中的一行。)(SET sql_mode = 'ONLY_FULL_GROUP_BY'不允许MySQL的非标准行为。)

select p.idpagu, count(*), p.pagu, p.target_kinerja, 
    sum(coalesce(pr.penarikan,0)) as pr_penarikan, 
    sum(coalesce(pr.target_kinerja,0)) as pr_target_kinerja, 
    sum(coalesce(r.realisasi,0)) as r_realisasi, 
    sum(coalesce(r.target_kinerja,0)) as r_target_kinerja, 
    p.pagu-sum(coalesce(r.realisasi,0)) as d_realisasi, 
    p.target_kinerja-sum(coalesce(r.target_kinerja,0)) as d_target_kinerja, 
    sum(coalesce(rr.realisasi,0)) as rr_realisasi 
from pagu p 
left join realisasi r on p.idpagu=r.idpagu and r.tgl BETWEEN "2017-01-01" and "2017-01-15" 
left join perencanaan pr on p.idpagu=pr.idpagu and r.tgl = pr.tgl and r.tgl BETWEEN "2017-01-01" and "2017-01-15" 
left join realisasi rr on p.idpagu=rr.idpagu and r.tgl = rr.tgl and r.tgl < "2017-01-15" 
group by p.idpagu, p.pagu, p.target_kinerja; 

idpagu pagu     pr_penarikan r_realisasi  d_realisasi    rr_target_kinerja 
    count(*)  target_kinerja pr_target_kinerja  r_target_kinerja d_target_kinerja  
1 1 52740000 1   0 0   52740000 1 0    0  52740000 
2 2 4732755000 120   0 0   20000000 20 4712755000  100  10000000 
3 1 12464938000 240   0 0   0   0 12464938000  240  0 
相关问题