我想显示表格中的所有重复记录,行是这样的
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
任何解决方案的人?
答案 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)列表,它们接近碰撞或碰撞(无论你选择什么语义)。下一步是获取您真正感兴趣的数据:
将l.uid = <uid>
添加到您的WHERE
。
添加GROUP BY l.uid, l.planet
,
将r.uid, r.planet
条款中的count(*) as counts
替换为SELECT
然后您甚至可以过滤:HAVING counts > 1
(HAVING
是您WHERE
之后的GROUP
当然,你可以
添加到您的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