2013-10-15 47 views
1

我正在寫一個查詢,我計算兩個不同的表,其中有一個外鍵約束(1:n)的總和。SQLite無法找到一種方法來避免笛卡爾積

enter image description here

因此,有表Kunde其持有的客戶。每個CustomerAdm維護。每Kunde有N個不同的交易(PbsRow),而每筆交易包含N個不同的產品(WarengruppeVK)。每筆交易都有月及年(MonatJahr

我需要的是一個包含以下信息的結果: 1)上將的名稱; 2)所有sollfrachthandling值的總和屬於一個在2013年這個特殊的海軍上將的客戶,3)屬於PbsRow S IN 2013客戶中的一所有nettodb_basis值的總和,4 & 5)同2)& 3)剛剛在2012

我已經嘗試了不同的東西,但我總是最終有一個笛卡爾產品sollfrachthandling值,當我做下一個表的加入。

請看看我的查詢:

SELECT vj.*, 
     j.*, 
     adm.ZNAME 
FROM ZADM adm, 
    (SELECT k.ZADMITARBEITER AS admidvj, 
      SUM(vk.ZNETTO) AS summeVJ, 
      SUM(vk.ZDB_BASIS) AS summeDBVJ, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtVJ, 
      SUM(p.ZHANDLING) AS handlingVJ 
    FROM ZWARENGRUPPEVK vk 
    LEFT JOIN ZPBSROW p ON p.Z_PK=vk.ZPBSROW 
    LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
    WHERE ZJAHR=2012 
    AND ZMONAT>=1 
    AND ZMONAT<=6 
    GROUP BY k.ZADMITARBEITER) vj, 
    (SELECT k.ZADMITARBEITER AS admidj, 
      SUM(vk.ZNETTO) AS summeJ, 
      SUM(vk.ZDB_BASIS) AS summeDBJ, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtJ, 
      SUM(p.ZHANDLING) AS handlingJ 
    FROM ZWARENGRUPPEVK vk 
    LEFT JOIN ZPBSROW p ON p.Z_PK=vk.ZPBSROW 
    LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
    WHERE ZJAHR=2013 
    AND ZMONAT>=1 
    AND ZMONAT<=6 
    GROUP BY k.ZADMITARBEITER) j 
WHERE vj.admidvj=j.admidj 
    AND vj.admidvj=adm.Z_PK 

我能做些什麼來避免這種笛卡爾積?當我從結果中刪除WarengruppeVK -table時,sollfrachthandling值是正確的。

在此先感謝。編輯: 這裏有一些樣品。

這是我從上面的查詢得到的結果: enter image description here

而這裏的結果,當我刪除了第一個加入: enter image description here

你會發現,sollfrachtVJhandlingVJ是現在不同了。它們取自發生笛卡爾產品的PbsRow。所以這2個值實際上是正確的,但我也需要我已經註釋過的2個值的總和。

這這裏後,我已經刪除了一個加入該SQL語句:

SELECT vj.*, 
     j.*, 
     adm.ZNAME 
FROM ZADM adm, 
    (SELECT k.ZADMITARBEITER AS admidvj, 
      --   SUM(vk.ZNETTO) AS summeVJ, 
--   SUM(vk.ZDB_BASIS) AS summeDBVJ, 

      SUM(p.ZSOLLFRACHT) AS sollfrachtVJ, 
      SUM(p.ZHANDLING) AS handlingVJ 
    FROM -- ZWARENGRUPPEVK vk 
ZPBSROW p -- LEFT JOIN ZPBSROW p ON p.Z_PK=vk.ZPBSROW 

    LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
    WHERE ZJAHR=2012 
    AND ZMONAT>=1 
    AND ZMONAT<=6 
    GROUP BY k.ZADMITARBEITER) vj, 
    (SELECT k.ZADMITARBEITER AS admidj, 
      SUM(vk.ZNETTO) AS summeJ, 
      SUM(vk.ZDB_BASIS) AS summeDBJ, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtJ, 
      SUM(p.ZHANDLING) AS handlingJ 
    FROM ZWARENGRUPPEVK vk 
    LEFT JOIN ZPBSROW p ON p.Z_PK=vk.ZPBSROW 
    LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
    WHERE ZJAHR=2013 
    AND ZMONAT>=1 
    AND ZMONAT<=6 
    GROUP BY k.ZADMITARBEITER) j 
WHERE vj.admidvj=j.admidj 
    AND vj.admidvj=adm.Z_PK 

EDIT 2

好吧,這裏包含了正確的結果的SQL語句,但是偏出4列。

SELECT vj.*, 
     j.*, 
     adm.ZNAME 
FROM ZADM adm, 
    (SELECT k.ZADMITARBEITER AS admidvj, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtVJ, 
      SUM(p.ZHANDLING) AS handlingVJ 
    FROM ZPBSROW p 
    LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
    WHERE ZJAHR=2012 
    AND ZMONAT>=1 
    AND ZMONAT<=6 
    GROUP BY k.ZADMITARBEITER) vj, 
    (SELECT k.ZADMITARBEITER AS admidj, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtJ, 
      SUM(p.ZHANDLING) AS handlingJ 
    FROM ZPBSROW p 
    LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
    WHERE ZJAHR=2013 
    AND ZMONAT>=1 
    AND ZMONAT<=6 
    GROUP BY k.ZADMITARBEITER) j 
WHERE vj.admidvj=j.admidj 
    AND vj.admidvj=adm.Z_PK 

正如你所看到的,summeJsummeVJsummeDBJsummeDBVJ不包括在內,這就是問題的所在。此結果中的所有值都是正確的,但我也需要在結果中包含這4個值。以上結果的第一個屏幕截圖包含正確的summeJ,summeVJ,0 summeDBJsummeDBVJ值,但是不正確的值爲handlingJ,handlingVJ,sollfrachtJsollfrachtVJ值。

編輯3:

我終於找到了一個辦法做到這一點。這是可以使用的查詢。這只是一對夫婦的子查詢:

SELECT ((summeJ-summeVJ)/summeVJ*100) AS abwNetto, 
     (summeJ-summeVJ) AS abwNettoAbs, 
     ((summeDBJ-summeDBVJ)/summeDBVJ*100) AS abwDB, 
     (summeDBJ-summeDBVJ) AS abwDBAbs, 
     t0.*, 
     t1.*, 
     adm.ZNAME 
FROM ZADM adm, 
    (SELECT vj.*, 
      j.* 
    FROM 
    (SELECT k.ZADMITARBEITER AS admidvj, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtVJ, 
      SUM(p.ZHANDLING) AS handlingVJ 
     FROM ZPBSROW p 
     LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
     WHERE ZJAHR=2012 
     AND ZMONAT>=1 
     AND ZMONAT<=6 
     GROUP BY k.ZADMITARBEITER) vj 
    LEFT JOIN 
    (SELECT k.ZADMITARBEITER AS admidj, 
      SUM(p.ZSOLLFRACHT) AS sollfrachtJ, 
      SUM(p.ZHANDLING) AS handlingJ 
     FROM ZPBSROW p 
     LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
     WHERE ZJAHR=2013 
     AND ZMONAT>=1 
     AND ZMONAT<=6 
     GROUP BY k.ZADMITARBEITER) j ON vj.admidvj = j.admidj) t0, 
    (SELECT vj.*, 
      j.* 
    FROM 
    (SELECT k.ZADMITARBEITER AS admidvj, 
      SUM(vk.ZNETTO) AS summeVJ, 
      SUM(vk.ZDB_BASIS) AS summeDBVJ 
     FROM ZPBSROW p 
     LEFT JOIN ZWARENGRUPPEVK vk ON vk.ZPBSROW=p.Z_PK 
     LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
     WHERE ZJAHR=2012 
     AND ZMONAT>=1 
     AND ZMONAT<=6 
     GROUP BY k.ZADMITARBEITER) vj 
    LEFT JOIN 
    (SELECT k.ZADMITARBEITER AS admidj, 
      SUM(vk.ZNETTO) AS summeJ, 
      SUM(vk.ZDB_BASIS) AS summeDBJ 
     FROM ZPBSROW p 
     LEFT JOIN ZWARENGRUPPEVK vk ON vk.ZPBSROW=p.Z_PK 
     LEFT JOIN ZKUNDE k ON k.Z_PK=p.ZKUNDE 
     WHERE ZJAHR=2013 
     AND ZMONAT>=1 
     AND ZMONAT<=6 
     GROUP BY k.ZADMITARBEITER) j ON vj.admidvj = j.admidj) t1 
WHERE t0.admidvj=t1.admidvj 
    AND t0.admidvj=adm.Z_PK 

enter image description here

+0

請顯示一些示例記錄和預期結果。 –

+0

我已經添加了一些示例記錄:-)。 Thx – gasparuff

+0

你說這些結果是錯誤的。請顯示您實際需要的一些*正確*結果以及它們的計算源記錄。 –

回答

2

的問題,您的加入是一切都連接在一起。 您應該使用獨立的標量子查詢:

SELECT name, 
     (SELECT SUM(WarengruppeVK.netto) 
     FROM Kunde 
     JOIN PbsRow ON Kunde.PK = PbsRow.kunde 
     JOIN WarengruppeVK ON PbsRow.PK = WarengruppeVK.pbsrow 
     WHERE Kunde.admitarbeiter = Adm.PK 
      AND PbsRow.jahr = 2012 
     ) AS vj_netto, 
     (SELECT SUM(PbsRow.sollfracht) 
     FROM Kunde 
     JOIN PbsRow ON Kunde.PK = PbsRow.kunde 
     WHERE Kunde.admitarbeiter = Adm.PK 
      AND PbsRow.jahr = 2012 
     ) AS vj_sollfracht 
     (SELECT SUM(WarengruppeVK.netto) 
     FROM Kunde 
     JOIN PbsRow ON Kunde.PK = PbsRow.kunde 
     JOIN WarengruppeVK ON PbsRow.PK = WarengruppeVK.pbsrow 
     WHERE Kunde.admitarbeiter = Adm.PK 
      AND PbsRow.jahr = 2013 
     ) AS j_netto, 
     (SELECT SUM(PbsRow.sollfracht) 
     FROM Kunde 
     JOIN PbsRow ON Kunde.PK = PbsRow.kunde 
     WHERE Kunde.admitarbeiter = Adm.PK 
      AND PbsRow.jahr = 2013 
     ) AS j_sollfracht 
FROM Adm 
+0

是的,我也想到了這一點,並想知道是否有其他解決方案,而不是分離查詢。感謝您的回答。 – gasparuff