2015-05-20 325 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秒內運行^^ !!!