【问题标题】:Count number of violations in different tables计算不同表中的违规次数
【发布时间】:2017-11-26 03:02:55
【问题描述】:

这个问题让我抓狂,因为我知道问题的根本原因,但不知道如何解决。这就是我要解决的问题 我有 3 张桌子:

_Table“Publisher”:列是“ASIN”、“publisher_ID”等。ASIN 当然是主键,因为 1 个出版商可以有很多书

_Table "Rights":权利侵犯。列是“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 中找到并且操作是“失败”(3),收到(6)。

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

问候,

【问题讨论】:

  • 发布到权限和发布到升级的加入导致您的计数被人为夸大。你必须先数数然后加入。
  • 那你能帮我做吗?我知道这应该很容易解决,但在过去的 2 天里它一直在杀死我 :)
  • “group by”语句应该包含在内部查询中。

标签: mysql sql count jointable


【解决方案1】:

我认为您需要在加入之前获取计数,因为第二次加入会人为地增加计数。

所以我们会有

Publisher  escalation right
1          A          Z
1          A          Y
1          A          X
2          A          1
2          B          1

因此,当您只想计算一次时,您将上述发布者 1 计算为三次。由于加入的 2 次升级,当您只想要一个时,您会为发布者 2 计算两次。

您从升级中获得计数并首先正确,然后加入。 (首选 imo)

或者,如果我们区分升级权,我们可能会得到正确的计数(假设我们正在计算每个表的 PK)更多的 co

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

其他引擎也支持窗口函数,也可以这样做,或者您可以使用用户变量模拟它们;但我认为上述概念之一应该可行。

【讨论】:

  • 哇,这太棒了。现在它有效。事实上,我的查询加入了很多表,所以让我们看看我是否可以模仿这个。希望我能。非常感谢:)
猜你喜欢
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多