【发布时间】:2013-10-15 13:57:27
【问题描述】:
我正在编写一个查询,在其中计算 2 个不同表的总和,这些表具有外键约束 (1:n)。
所以有一张桌子Kunde 持有客户。每个Customer 都由Adm 维护。每个Kunde 有N 个不同的事务(PbsRow),而每个事务包含N 个不同的产品(WarengruppeVK)。每笔交易都有一个月和一年(Monat 和 Jahr)
我需要的是包含以下信息的结果:
1) Adm 的名称,2) 2013 年属于该特定 Adm 的客户之一的所有 sollfracht 和 handling 值的总和,3) 属于的所有 netto 和 db_basis 值的总和该客户在 2013 年的 PbsRows 之一,4 和 5) 与 2) 和 3) 仅在 2012 年相同
我已经尝试了不同的方法,但是当我使用下一个表进行联接时,我总是得到一个具有 sollfracht 和 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
我可以做些什么来避免这个笛卡尔积?当我从结果中删除 WarengruppeVK-table 时,sollfracht 和 handling 的值是正确的。
提前致谢。
编辑: 以下是一些示例。
这是我从上面的查询中得到的结果:
这是我删除第一个连接时的结果:
您会注意到 sollfrachtVJ 和 handlingVJ 现在不同了。它们取自笛卡尔积发生的PbsRow。所以这2个值实际上是正确的,但我还需要我注释掉的2个值的总和。
这是我删除那个 Join 后的 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
编辑 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
如您所见,summeJ、summeVJ、summeDBJ 和 summeDBVJ 不包括在内,这就是问题所在。此结果中的所有值都是正确的,但我的结果中还需要包含这 4 个值。我上面结果的第一个屏幕截图包含正确的 summeJ、summeVJ、summeDBJ 和 summeDBVJ 值,但不正确的 handlingJ、handlingVJ、sollfrachtJ 和 sollfrachtVJ 值。
编辑 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
【问题讨论】:
-
请展示一些示例记录和预期结果。
-
我添加了一些示例记录:-)。谢谢
-
你说这些结果是错误的。请显示一些您真正想要的正确结果,以及计算它们的源记录。
-
好的,我希望这会有所帮助。
标签: sql sqlite cartesian-product