2013-02-22 44 views
1

所以我有一个表,my_table有一个主键,idINT),并进一步列fooVARCHAR)和barDOUBLE)。每foo应出现一次在我的表中,与相关bar值,但我知道我有几个行与foo相同不同bar s。如何获得包含相同foo值但具有不同bar s(例如,相差超过10)的那些行的列表? 我想:MySQL表自连接返回的行数太多

 
    SELECT t1.id, t1.bar, t2.id, t2.bar, t1.foo 
    FROM my_table t1, my_table t2 
    WHERE t1.foo=t2.foo 
    AND t1.bar - t2.bar > 10.; 

,但我得到很多很多的结果(比中行my_table的总数还多)。我觉得我一定在做一些非常明显的愚蠢行为,但是看不到我的错误。

啊 - 谢谢SWeko:我想我明白为什么我会得到如此多的结果。有没有计算SQL的方法,对于每个foofoobar之间的差值大于10的行数。

+0

相差10 t1.bar - t2.bar = 10 – 2013-02-22 15:43:26

+0

我想他的意思相差至少10 – 2013-02-22 15:44:01

回答

0

如果,例如,你有5列foo='A'和10行与foo='B'自联接将加入每一个行与对方行(包括其本身),并且每个B-行彼此B-行,所以一个简单的

SELECT t1.id, t1.bar, t2.id, t2.bar, t1.foo 
FROM my_table t1, my_table t2 
WHERE t1.foo=t2.foo 

将返回5*5+10*10=125行。过滤值会削减该数字,但您可能仍然有(显着)多于您开始使用的行数。例如。如果我们假设在B行有5 bar通过50分别值,这将意味着他们将匹配有:

bar = 5 - 0 rows that have bar less than -5 
bar = 10 - 0 rows that have bar less than 0 
bar = 15 - 0 rows that have bar less than 5 
bar = 20 - 1 rows that have bar less than 10 
bar = 25 - 2 rows that have bar less than 15 
bar = 30 - 3 rows that have bar less than 20 
bar = 35 - 4 rows that have bar less than 25 
bar = 40 - 5 rows that have bar less than 30 
bar = 45 - 6 rows that have bar less than 35 
bar = 50 - 7 rows that have bar less than 40 

所以你将有28个成绩为B-行独自一人,那数字随着具有相同值foo的行的平方上升。

-1

您是否尝试过使用“新”JOIN语法的相同内容?

SELECT t1.*, 
      t2.* 
     FROM my_table t1 
     JOIN my_table t2 ON t1.foo = t2.foo 
    WHERE (t1.bar - t2.bar) > 10 

我不怀疑这会解决你的问题,但对我来说,至少在哪里我会开始。

我也可以试试这个:

SELECT t1.*, 
      t2.* 
     FROM my_table t1 
     JOIN my_table t2 ON t1.foo = t2.foo AND t1.id != t2.id 
    WHERE (t1.bar - t2.bar) > 10 
+0

这是首选,但它显然不是问题,因为它完全等同于OP的查询。 – 2013-02-22 15:46:24

+0

-1添加的查询没有意义。一行永远不会加入自己,因为您已经要求匹配的行具有不同的bar值。只是“尝试”随机的东西并希望问题消失是不好的。你必须真正弄清楚并修复它! – 2013-02-22 15:52:09

+0

你为什么恨我,dan1111? – 2013-02-22 16:04:34

2

要回答你的问题的最新:

是否有票的SQL的方式,为每个FOO,行 与富,但酒吧超过10不同的是多少?

这样的查询应该工作:

select t1.id, t1.foo, t1.bar, count(t2.id) as dupes 
from my_table t1 
    left outer join my_table t2 on t1.foo=t2.foo and (t1.bar - t2.bar) > 10 
group by t1.id, t1.foo, t1.bar;