【问题标题】:MySQL get duplicate rows in subqueryMySQL在子查询中获取重复行
【发布时间】:2018-02-09 10:55:20
【问题描述】:

我想显示我表中所有重复的记录,行是这样的

uid   planet degree    
1     1      104
1     2      109
1     3      206
2     1      40
2     2      76
2     3      302

我在子查询中有许多不同的OR 语句,它们具有不同的组合,我想计算每个匹配的语句,但它只显示每个行星和度数的第一个匹配项。

查询:

    SELECT DISTINCT
  p.uid,
  (SELECT COUNT(*)
   FROM Params AS p2
   WHERE p2.uid = p.uid
  AND(
(p2.planet = 1 AND p2.degree BETWEEN 320 - 10 AND 320 + 10) OR
          (p2.planet = 7 AND p2.degree BETWEEN 316 - 10 AND 316 + 10)
                            ...Some more OR statements...
     )
      ) AS counts FROM Params AS p HAVING counts > 0 ORDER BY p.uid DESC

有什么解决办法吗?

【问题讨论】:

  • 删除不同
  • 没有不同的行重复但计数仍然相同,注意子查询没有不同的
  • 显示整个查询和数据
  • 我把它放在 txt 文件中我认为这是唯一的显示方式:flash.ge/query.txt
  • 这个查询是谁提出的? (是自动生成还是人工制造?)

标签: mysql count duplicates subquery rows


【解决方案1】:

更新

因此,大多数人在使用计数加入子查询组查询时遇到的问题是基本查询不正确,对于这个问题,以下内容似乎完全是矫枉过正;o)

基础数据

在这个特定的示例中,您首先想要的数据基础是:

(uidA, planetA, uidB, planetB) 代表玩家 A 和玩家 B 行星的每个组合。那个很简单(l 代表左,r 代表右):

SELECT l.uid, l.planet, r.uid, r.planet
FROM params l, params r

第一步完成。

过滤数据

现在您要确定 - 对于一行,即一对行星 - 行星是否相撞(或几乎相撞)。这就是WHERE 的用武之地。

WHERE ABS(l.degree-r.degree) < 10

例如,只会留下那些度数差异小于 10 的行星对。更复杂的东西是可能的(你疯狂的条件......),例如,如果行星的直径不同,你可以添加额外的东西.但是,我的建议是,您将查询中的一些额外数据放入表中。

例如,如果所有 1st 行星的玩家都具有相同的大小,您可以有一个带有 (planet_id, size) 的表。如果每个行星都可以有不同的大小,请将大小作为一列添加到 params 表中。

那么你的WHERE 子句可能是这样的:

WHERE l.size+r.size < ABS(l.degree-r.degree)

例如,如果两个大小为 5 和 10 的大行星应至少相距 15 度,则此查询将找到所有不相距的行星。

我们假设,你有一个很好的条件,所以在这一点上,我们有一个(uidA,planetA,uidB,planetB)的行星列表,它们接近碰撞或碰撞(无论你选择什么语义)。下一步是获取您真正感兴趣的数据:

将 uidA 限制为特定的 user_id(例如当前登录的用户)

l.uid = &lt;uid&gt; 添加到您的WHERE

计算每个行星 A,存在多少行星 B,威胁碰撞

添加GROUP BY l.uid, l.planet

在您的 SELECT 子句中将 r.uid, r.planet 替换为 count(*) as counts

然后你甚至可以过滤:HAVING counts &gt; 1HAVINGWHERE,因为你有GROUPed)

当然可以

过滤掉某些可能与玩家 A 没有行星互动的玩家 B

添加到您的WHERE

r.uid NOT IN (1)

只发现自我碰撞

WHERE l.uid = r.uid

只查找非自身碰撞

WHERE l.uid <> r.uid

只查找与一个特定行星的碰撞

WHERE l.planet = 1

结论

从正确的基础数据开始,然后对其进行适当过滤,然后对其进行分组的结构化方法通常是最佳方法。如果您对某些概念不清楚,请在线阅读它们,到处都有手册

最终查询可能看起来像这样

SELECT l.uid, l.planet, count(*) as counts
FROM params l, params r
WHERE [ collision-condition ]
GROUP BY l.uid, l.planet
HAVING counts > 0

如果你想碰撞一个非行星对象,你可能想创建一个“虚拟表”,而不是 FROM params l, params r 你这样做(可能有不同的字段,我只是假设你添加一个大小字段以某种方式使用):

FROM params l, (SELECT 240 as degree, 2 as planet, 5 as size) r

多个:

FROM params l, (SELECT 240 as degree, 2 as planet, 5 as size 
                UNION 
                SELECT 250 as degree, 3 as planet, 10 as size 
                UNION ...) r

【讨论】:

  • 好吧,让我们把一些事情说清楚,每个玩家有 18 个行星,每个行星都有自己的度数,是的,我正在尝试找出哪些行星与另一个行星接近等等,但真正的问题是我想多次计算相同的行,因为在我的组合中可以多次匹配一行,但我当前的查询只给了我一次,它跳过了同一行的下一个匹配项
  • 现在我正在考虑这个解决方案flash.ge/joins.txt,加入每条语句(我有 182 条)你怎么看?值得一试吗?
  • 关于碰撞的问题:可能来自一个玩家或多个玩家(或两者)的行星相撞?表示其中哪对可能发生碰撞:(uid1,planet1),(uid1,planet2),(uid2,planet1)。哦,你提议的连接看起来很混乱,就像无效的 sql ^^
  • 关于碰撞的答案:一个玩家多个行星可以与另一个玩家一个行星发生碰撞,这就是我卡住的地方,因为它只显示一个碰撞((uid1,planet1)和(uid1,planet2)与(uid2) ,行星1))。是的,我知道无效的 sql,它只是为了显示目的
  • 会调整我的帖子,这需要一些时间。
猜你喜欢
  • 2011-10-26
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多