这个问题让我疯狂,因为我知道问题的根本原因,但不知道如何修复它。这是我试图解决的问题 我有3张桌子:
_Table"发布者":列是" ASIN"," publisher_ID"等。当然,ASIN将是主键,因为1个发布者可以拥有很多书
_Table"权利":侵犯权利。列是" ASIN","违规类型","行动" (或者“失败”或“通过”等)所以1 ASIN可以多次动作(例如:ASIN A - 商标 - 失败,ASIN A - 版权 - 通过等。 )
_Table" Escalations":我们收到的升级。列是" ASIN"等等。
当然这些表有更多列,但列出的列更相关。
现在我的目的是当我输入发布商ID时,我希望查询能够向我提供我们为该发布商收到的升级计数,以及该发布商失去权利的图书数量
所以这就是我所拥有的
SELECT publisher_ID,
num_of_rights_violations,
num_of_escalations
FROM (SELECT p.publisher_ID,
sum(if(e.asin = p.asin, 1, 0)) as num_of_escalations,
sum(if(r.asin = p.asin and r.acion = 'fail'),1,0) as num_of_rights_violations
FROM publisher p
LEFT JOIN rights r
ON r.asin = p.asin
LEFT JOIN escalations e
ON e.asin = p.asin
WHERE p.publisher_ID = 'xxx'
GROUP BY p.publisher_ID) a
然而,结果非常奇怪。因此,对于此发布者,只有3个ASIN因权利违规而失败。这3个ASIN总共上升了6次。该出版商共上传了18次。因此,正确的结果应该是: xxx - 3 - 18 。但它给了我 xxx - 6 - 18 。所以我怀疑是出于某种原因对于num_of_rights_violation,我的联合函数返回了ASIN的总计升级,在表r中找到并且操作失败了#39; (3),收到(6)。
有人可以帮我解决这个问题吗?
此致
答案 0 :(得分:0)
我认为你需要在连接之前得到计数,因为第二次连接是人为地增加计数。
所以我们有
Publisher escalation right
1 A Z
1 A Y
1 A X
2 A 1
2 B 1
所以当你只想算一次时,你在上面对出版商1进行了三次计算。当你只想要一个因为加入的2次升级时,你会为发布者2计算两次。
您从升级和右FIRST获得计数,然后加入。 (首选imo)
或者,如果我们区分升级权利,我们可能得到正确的计数(假设我们正在计算每个表的PK)更多合作
SELECT p.publisher_ID
, num_of_escalations,
, num_of_rights_violations
FROM publisher p
LEFT JOIN (SELECT asin, count(*) as Num_of_Escalations
FROM rights where acion = 'fail'
GROUP BY asin) r
ON r.asin = p.asin
LEFT JOIN (SELECT asin, count(*) as num_of_rights_violations
FROM escalations
GROUP BY asin) e
ON e.asin = p.asi
WHERE p.publisher_ID = 'xxx'
另一种可行的方法是从每个表的主键计算不同的值。
SELECT p.publisher_ID
, count(distinct e.pk) as num_of_escalations --assume each table has a pk change the pk to the primary key field of table
, count(distinct r.pk) as num_of_rights_violations --assume each table has a pk change the pk to the primary key field of table
FROM publisher p
LEFT JOIN rights r
ON r.asin = p.asin
AND r.acion='fail' --moved limit to join
LEFT JOIN escalations e
ON e.asin = p.asin
WHERE p.publisher_ID = 'xxx'
GROUP BY p.publisher_ID
替代引擎也支持可以执行此操作的窗口函数,或者您可以使用用户变量来模拟它们;但我认为上述概念之一应该有效。