计算不同表格中

时间:2017-06-22 17:39:01

标签: mysql sql count jointable

这个问题让我疯狂,因为我知道问题的根本原因,但不知道如何修复它。这是我试图解决的问题 我有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)。

有人可以帮我解决这个问题吗?

此致

1 个答案:

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

替代引擎也支持可以执行此操作的窗口函数,或者您可以使用用户变量来模拟它们;但我认为上述概念之一应该有效。