2015-05-20 129 views
0

你好家伙我有3个表。 下面是创建数据:聚合与汇总和空记录

CREATE TABLE `positionstyp` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`parent_id` int(11) DEFAULT NULL, 
`bau_nr_komplett` varchar(32) NOT NULL, 
PRIMARY KEY (`id`), 
KEY `parent_id` (`parent_id`), 
CONSTRAINT `positionstyp_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `positionstyp` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB; 

CREATE TABLE `projektposition` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`projekt_id` int(11) NOT NULL, 
`preis_vertragskosten` float DEFAULT NULL, 
`positionstyp_id` int(11), 
PRIMARY KEY (`id`), 
KEY `positionstyp_id` (`positionstyp_id`), 
CONSTRAINT `fk_projektposition_positionstypID` FOREIGN KEY (`positionstyp_id`) REFERENCES `positionstyp` (`id`) ON UPDATE CASCADE 
) ENGINE=InnoDB; 

CREATE TABLE `menge` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`baufortschritt` int(11) NOT NULL DEFAULT 0, 
`menge` float NOT NULL, 
`projektposition_id` int(11) NOT NULL, 
PRIMARY KEY (`id`), 
KEY `projektposition_id` (`projektposition_id`), 
CONSTRAINT `menge_ibfk_10` FOREIGN KEY (`projektposition_id`) REFERENCES `projektposition` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB; 

INSERT INTO `positionstyp` (`id`, `parent_id`, `bau_nr_komplett`) VALUES 
(1, NULL, '1'), 
(2, NULL, '2'), 
(3, NULL, '3'), 
(4, NULL, '4'), 
(5, NULL, '5'), 
(6, NULL, '6'), 
(7, 3, '325'), 
(8, 7, '325.0'), 
(9, 7, '325.1'), 
(10, 8, '325.0.0'); 

INSERT INTO `projektposition` (`id`, `projekt_id`, `preis_vertragskosten`, `positionstyp_id`) VALUES 
(1, 1325, 100, 3), 
(2, 1325, 300, 7), 
(3, 1325, 150, 7), 
(4, 1325, 200, 10), 
(5, 1325, 50, 9); 

INSERT INTO `menge` (`id`, `menge`, `baufortschritt`, `projektposition_id`) VALUES 
(1, 10, 1, 1), 
(2, 20, 20, 2), 
(3, 30, 30, 3), 
(4, 40, 40, 4), 
(5, 50, 100, 5), 
(6, 60, 87, 1), 
(7, 70, 90, 2), 
(8, 80, 10, 3), 
(9, 90, 50, 4), 
(10, 100, 0, 5), 
(11, 1000, 100, 5), 
(12, 100, 10, 6); 

A “猛恶” 被绑定到一个 “projektposition” 和 “projektposition” 被绑定到一个 “positionstyp”。那么“positionstyp”可能有一个父级“positionstyp”。

在“menge”中有一个“menge”字段和一个称为“menge”的字段“baufortschritt”。然后字段“preis_vertragskosten”给这个组合一个价格。

所以价格的猛恶是(mengemenge * mengebaufortschritt * projektpositionpreis_vertragskosten

在我的选择我想总结的价格,也是 “positionstyp” -entries所有 “positionstyp” -entries在它下面没有“menge”/“projektposition”,所以没有价格,只能用于特定的“projekt_id”

我的第一次尝试是按分组汇总的,但是没有价格的所有“positionstyp”都失败了。

现在我有这个代码,来到附近我想要的东西:

SELECT 
    pt.id, 
    pt.parent_id, 
    SUM(IF(m.menge IS NULL,0, m.menge * p.preis_vertragskosten * m.baufortschritt/100 * (p.projekt_id=1325))) as summe, 
    pt.bau_nr_komplett 
FROM positionstyp pt 
LEFT JOIN projektposition p  ON (p.positionstyp_id=pt.id) 
LEFT JOIN menge m  ON (m.projektposition_id=p.id) 
GROUP BY pt.id 

输出正确的,当然,但总结了门奇不总结了递归positionstyp_parents。 positionstyp-table的递归性更容易在bau_nr_komplett字段中找到:positionstyp是所有positionstyp的孩子,那bau_nr_komplett是孩子positionstyp的开始s bau_nr_komplett`(不一定是直接的孩子)。

是否有一些想法?

感谢和问候, 托比亚斯

结果现在是:

bau_nr_komplett summe 
       1  0  
       2  0  
       3  5230  
       4  0  
       5  0  
       6  0  
      325 22650  
      325.0  0  
      325.1 52500  
     325.0.0 12200 

期望的结果是:

bau_nr_komplett summe 
       1 0  
       2 0  
       3 5230+22650+52500+12200  
       4 0  
       5 0  
       6 0  
      325 22650+52500+12200  
      325.0 12200  
      325.1 52500  
     325.0.0 12200 

- 编辑2: 我发现了一个坏的解决方案。坏意味着它与测试数据集一起工作。但与真正的数据库和数据集的100.000s它需要一个半小时; d

SELECT pt.bau_nr_komplett, (
SELECT 
    SUM(IF(m1.menge IS NULL,0,m1.menge*p1.preis_vertragskosten*m1.baufortschritt/100*(p1.projekt_id=1325))) 
FROM positionstyp pt1 
LEFT JOIN projektposition p1 ON (p1.positionstyp_id = pt1.id) 
LEFT JOIN menge m1 ON (m1.projektposition_id = p1.id) 
WHERE pt1.bau_nr_komplett LIKE CONCAT(pt.bau_nr_komplett, "%") 
) as summe 
FROM positionstyp pt 
LEFT JOIN projektposition p ON (p.positionstyp_id = pt.id) 
LEFT JOIN menge m ON (m.projektposition_id = p.id) 
GROUP BY pt.id 
+0

期望的结果是什么? – Strawberry

+0

而positionstyp_id是如何“DEFAULT NULL”!?!?!?!? – Strawberry

+0

以上所需的结果,在html中,对不起。 DEFAULT NULL是一个复制错误 – dobberph

回答

0

我找到了答案,为自己,也增加了一些详细的资料:

CREATE PROCEDURE `getProjektsummen`(IN projektID int) 
BEGIN 
SELECT tttt.id, tttt.parent_id, tttt.bau_nr_komplett, tttt.summe_kostenanschlag, tttt.summe_kostenanschlag_baufortschritt, 
tttt.summe_vertragskosten, tttt.summe_vertragskosten_baufortschritt, 
tttt.summe_gemittelteangebotskosten, tttt.summe_gemittelteangebotskosten_baufortschritt 
FROM (

SELECT id, parent_id,bau_nr_komplett, summe_kostenanschlag, summe_kostenanschlag_baufortschritt, 
summe_vertragskosten, summe_vertragskosten_baufortschritt, 
summe_gemittelteangebotskosten, summe_gemittelteangebotskosten_baufortschritt 
FROM 
(SELECT tt.id, tt.parent_id, tt.bau_nr_komplett, 
MAX(tt.summe_kostenanschlag) as summe_kostenanschlag,MAX(tt.summe_kostenanschlag_baufortschritt) as summe_kostenanschlag_baufortschritt, 
MAX(tt.summe_vertragskosten) as summe_vertragskosten,MAX(tt.summe_vertragskosten_baufortschritt) as summe_vertragskosten_baufortschritt, 
MAX(tt.summe_gemittelteangebotskosten) as summe_gemittelteangebotskosten,MAX(tt.summe_gemittelteangebotskosten_baufortschritt) as summe_gemittelteangebotskosten_baufortschritt 
FROM (
SELECT ptt.id, ptt.parent_id, coalesce(t.sub9,t.sub8,t.sub7,t.sub6,t.sub5,t.sub4,t.sub3,t.sub2,t.sub1) as bau_nr_komplett, 
    ROUND(IFNULL(t.summe_kostenanschlag,0),0) as summe_kostenanschlag, 
    ROUND(IFNULL(t.summe_kostenanschlag_baufortschritt,0),0) as summe_kostenanschlag_baufortschritt, 
    ROUND(IFNULL(t.summe_vertragskosten,0),0) as summe_vertragskosten, 
    ROUND(IFNULL(t.summe_vertragskosten_baufortschritt,0),0) as summe_vertragskosten_baufortschritt, 
    ROUND(IFNULL(t.summe_gemittelteangebotskosten,0),0) as summe_gemittelteangebotskosten, 
    ROUND(IFNULL(t.summe_gemittelteangebotskosten_baufortschritt,0),0) as summe_gemittelteangebotskosten_baufortschritt 
FROM 
(
SELECT DISTINCT 
    sum(menge * preis_kostenanschlag *(p.projekt_id=projektID)) as summe_kostenanschlag, 
    sum(menge * preis_kostenanschlag * baufortschritt/100 *(p.projekt_id=projektID)) as summe_kostenanschlag_baufortschritt, 
    sum(menge * preis_vertragskosten *(p.projekt_id=projektID)) as summe_vertragskosten, 
    sum(menge * preis_vertragskosten * baufortschritt/100 *(p.projekt_id=projektID)) as summe_vertragskosten_baufortschritt, 
    sum(menge * preis_gemittelte_angebotskosten *(p.projekt_id=projektID)) as summe_gemittelteangebotskosten, 
    sum(menge * preis_gemittelte_angebotskosten * baufortschritt/100 *(p.projekt_id=projektID)) as summe_gemittelteangebotskosten_baufortschritt, 
    SUBSTRING(pt.bau_nr_komplett,1,1) as sub1, 
    SUBSTRING(pt.bau_nr_komplett,1,2) as sub2, 
    SUBSTRING(pt.bau_nr_komplett,1,3) as sub3, 
    SUBSTRING(pt.bau_nr_komplett,1,4) as sub4, 
    SUBSTRING(pt.bau_nr_komplett,1,5) as sub5, 
    SUBSTRING(pt.bau_nr_komplett,1,6) as sub6, 
    SUBSTRING(pt.bau_nr_komplett,1,7) as sub7, 
    SUBSTRING(pt.bau_nr_komplett,1,8) as sub8, 
    SUBSTRING(pt.bau_nr_komplett,1,9) as sub9 
FROM menge m 
    join projektposition p ON (m.projektposition_id=p.id) 
    join positionstyp pt ON (p.positionstyp_id=pt.id) 
GROUP BY SUBSTRING(pt.bau_nr_komplett,1,1), 
SUBSTRING(pt.bau_nr_komplett,1,2), 
SUBSTRING(pt.bau_nr_komplett,1,3), 
SUBSTRING(pt.bau_nr_komplett,1,4), 
SUBSTRING(pt.bau_nr_komplett,1,5), 
SUBSTRING(pt.bau_nr_komplett,1,6), 
SUBSTRING(pt.bau_nr_komplett,1,7), 
SUBSTRING(pt.bau_nr_komplett,1,8), 
SUBSTRING(pt.bau_nr_komplett,1,9) 
WITH ROLLUP 
) t join positionstyp ptt on (coalesce(t.sub9,t.sub8,t.sub7,t.sub6,t.sub5,t.sub4,t.sub3,t.sub2,t.sub1) = ptt.bau_nr_komplett) 
WHERE 
LENGTH(coalesce(t.sub9,t.sub8,t.sub7,t.sub6,t.sub5,t.sub4,t.sub3,t.sub2,t.sub1))<>2 AND 
SUBSTRING(reverse(coalesce(t.sub9,t.sub8,t.sub7,t.sub6,t.sub5,t.sub4,t.sub3,t.sub2,t.sub1)),1,1) <> '.' AND 
(
(ISNULL(t.sub9) AND NOT ISNULL(t.sub8) AND LENGTH(t.sub8)=8) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND NOT ISNULL(t.sub7) AND LENGTH(t.sub7)=7) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND ISNULL(t.sub7) AND NOT ISNULL(t.sub6) AND LENGTH(t.sub6)=6) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND ISNULL(t.sub7) AND ISNULL(t.sub6) AND NOT ISNULL(t.sub5) AND LENGTH(t.sub5)=5) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND ISNULL(t.sub7) AND ISNULL(t.sub6) AND ISNULL(t.sub5) AND NOT ISNULL(t.sub4) AND LENGTH(t.sub4)=4) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND ISNULL(t.sub7) AND ISNULL(t.sub6) AND ISNULL(t.sub5) AND ISNULL(t.sub4)AND NOT ISNULL(t.sub3) AND LENGTH(t.sub3)=3) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND ISNULL(t.sub7) AND ISNULL(t.sub6) AND ISNULL(t.sub5) AND ISNULL(t.sub4) AND ISNULL(t.sub3)AND NOT ISNULL(t.sub2) AND LENGTH(t.sub2)=2) OR 
(ISNULL(t.sub9) AND ISNULL(t.sub8) AND ISNULL(t.sub7) AND ISNULL(t.sub6) AND ISNULL(t.sub5) AND ISNULL(t.sub4) AND ISNULL(t.sub3) AND ISNULL(t.sub2)AND NOT ISNULL(t.sub1) AND LENGTH(t.sub1)=1)) 
UNION 
SELECT pptt.id as id, pptt.parent_id as parent_id, pptt.bau_nr_komplett as bau_nr_komplett, 
0 as summe_kostenanschlag, 
0 as summe_kostenanschlag_baufortschritt, 
0 as summe_vertragskosten, 
0 as summe_vertragskosten_baufortschritt, 
0 as summe_gemittelteangebotskosten, 
0 as summe_gemittelteangebotskosten_baufortschritt 
FROM positionstyp pptt 
) tt 
GROUP BY tt.id) ttt 
UNION 
SELECT p1.id, null, concat(pt1.bau_nr_komplett," #"), 
    IFNULL(ROUND(sum(m1.menge * p1.preis_kostenanschlag),0),0) as summe_kostenanschlag, 
    IFNULL(ROUND(sum(m1.menge * p1.preis_kostenanschlag * m1.baufortschritt/100),0),0) as summe_kostenanschlag_baufortschritt, 
    IFNULL(ROUND(sum(m1.menge * p1.preis_vertragskosten),0),0) as summe_vertragskosten, 
    IFNULL(ROUND(sum(m1.menge * p1.preis_vertragskosten * m1.baufortschritt/100),0),0) as summe_vertragskosten_baufortschritt, 
    IFNULL(ROUND(sum(m1.menge * p1.preis_gemittelte_angebotskosten),0),0) as summe_gemittelteangebotskosten, 
    IFNULL(ROUND(sum(m1.menge * p1.preis_gemittelte_angebotskosten * m1.baufortschritt/100),0),0) as summe_gemittelteangebotskosten_baufortschritt 
FROM menge m1 JOIN projektposition p1 ON (m1.projektposition_id=p1.id) JOIN positionstyp pt1 ON (p1.positionstyp_id=pt1.id) 
WHERE p1.projekt_id=projektID AND p1.positionstyp_id IS NOT NULL 
GROUP BY p1.id 
) tttt 
ORDER BY tttt.bau_nr_komplett; 
END 

,我很高兴它可以在超过100万个数据集的情况下工作,在投影中有10000个数据集,在位置为 时可以在2.5秒内运行^^ !!!