MySQL在子查询中获取重复的行

时间:2017-08-31 13:08:11

标签: mysql count duplicates subquery rows

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

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

任何解决方案的人?

1 个答案:

答案 0 :(得分:2)

<强>更新

因此,大多数人对其计数加入子查询组查询的问题是基本查询不正确,以下看起来似乎对此问题完全有效; o)< / p>

基础数据

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

(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的行星。更复杂的东西是可能的(你的疯狂条件......),例如如果行星有不同的直径,你可以添加额外的东西。但是,我的建议是,您将查询中的一些其他数据放入表中。

例如,如果所有第一行星玩家具有相同的大小,则可以使用(planet_id,size)的表格。如果每个行星都有不同的大小,请将该大小作为列添加到参数表中。

那么你的WHERE条款就像:

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

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

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

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

l.uid = <uid>添加到您的WHERE

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

添加GROUP BY l.uid, l.planet

r.uid, r.planet条款中的count(*) as counts替换为SELECT

然后您甚至可以过滤:HAVING counts > 1HAVING是您WHERE之后的GROUP

当然,你可以

过滤掉某些可能与玩家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