SQLite找不到避免笛卡尔积的方法

时间:2013-10-15 13:57:28

标签: sql sqlite cartesian-product

我正在编写一个查询,我正在计算2个不同表的总和,这些表具有外键约束(1:n)。

enter image description here

所以有表Kunde持有客户。每个Customer都由Adm维护。每个Kunde都有N个不同的交易(PbsRow),而每个交易都包含N个不同的产品(WarengruppeVK)。每笔交易都有一个月和一年(MonatJahr

我需要的是一个包含以下信息的结果: 1)Adm的名称,2)2013年属于此特定Adm的一个客户的所有sollfrachthandling值的总和,3)所有netto和{的总和{1}}属于2013年该客户的db_basis之一的值,4& 5)与2)相同3)仅在2012年

我已经尝试了不同的东西,但是当我使用下一个表格进行连接时,我总是会得到一个带有PbsRowsollfracht值的笛卡尔积。

请查看我的查询:

handling

我可以做些什么来避免使用这种笛卡尔产品?当我从结果中删除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 - 表时,WarengruppeVKsollfracht值是正确的。

提前致谢。

编辑: 以下是一些样本。

这是我从上面的查询得到的结果: enter image description here

这是我删除第一个连接时的结果: enter image description here

您会注意到handlingsollfrachtVJ现在不同了。它们来自handlingVJ笛卡尔积的发生地。所以这两个值实际上是正确的,但我还需要我已经注释掉的两个值的总和。

这是我删除了一个Join之后的SQL语句:

PbsRow

编辑2

好的,这是包含正确结果的SQL语句,但是错过了4列。

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

如您所见,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 summeJsummeVJsummeDBJ未包含在内,这就是问题所在。此结果中的所有值都是正确的,但我还需要在结果中包含这4个值。上述结果的第一个屏幕截图包含正确的summeDBVJsummeJsummeVJsummeDBJ值,但不正确summeDBVJhandlingJ,{{ 1}}和handlingVJ值。

编辑3:

我终于找到了办法。这是有效的查询。它只是几个子查询:

sollfrachtJ

enter image description here

1 个答案:

答案 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