从mysql中检索不存在的值,也不检索附近的值

时间:2015-02-01 22:09:02

标签: mysql

我正在寻找不仅在给定表中不存在,而且相关值也不存在的值。有效值在-5和5之间是二维的,总共121个值(给定其他约束)。

所以,对于前者,我有以下几点:

select x,y from (
  select
   v.x,
   w.y
  from 
   (select '-5' as x union all select '-4' union all select '-3' union all select '-2' union all select '-1' union all select '0' union all select '1' union all select '2' union all select '3' union all select '4' union all select '5') as v
  join
   (select '-5' as y union all select '-4' union all select '-3' union all select '-2' union all select '-1' union all select '0' union all select '1' union all select '2' union all select '3' union all select '4' union all select '5') as w
  left join
   (select x,y,id from building where body_id = ?) as b on v.x = b.x and w.y = b.y
  where
   b.id is null
) as t

这给了我一个x,y坐标的列表,它们没有“建筑物”。但是,我想知道的是,如果有任何x,y不仅是空的,而是围绕它的那些(x-1到x + 1,y-1到y + 1)也是空的。根据定义,任何+/- 5的x和+/- 5的任何y都不一定会将所有周围的x都清空。

最糟糕的情况是,我想,正在提取上述信息并在每个值上搜索自己以查看是否找不到所有周围的值。我要求更多使用它作为学习更多SQL的借口。

1 个答案:

答案 0 :(得分:2)

您的查询的关键概念是这一行: on v.x = b.x and w.y = b.y 。 (从这个小片段到最后:

(select x,y,id from building where body_id = ?) as b on v.x = b.x and w.y = b.y where b.id is null

这意味着您只对v.x和w.y恰好位于建筑物坐标上的连接感兴趣。

改变这种状况很简单。例如,尝试这样的事情:

select x,y from 
(
    select v.x, w.y from 
    (
        select '-5' as x union all select '-4' union all select '-3' union all select '-2' union all select '-1' union all select '0' union all select '1' union all select '2' union all select '3' union all select '4' union all select '5'
    ) as v
    join
    (
        select '-5' as y union all select '-4' union all select '-3' union all select '-2' union all select '-1' union all select '0' union all select '1' union all select '2' union all select '3' union all select '4' union all select '5'
    ) as w
    left join    
    (
        select x,y,id from building where body_id = ?
    ) as b 
    on 
    (
        (v.x + 1 = b.x and w.y + 1= b.y) OR
        (v.x + 1 = b.x and w.y = b.y) OR
        (v.x + 1 = b.x and w.y - 1= b.y) OR
        (v.x = b.x and w.y + 1= b.y) OR
        (v.x = b.x and w.y = b.y) OR
        (v.x = b.x and w.y - 1= b.y) OR
        (v.x - 1 = b.x and w.y + 1= b.y) OR
        (v.x - 1 = b.x and w.y = b.y) OR
        (v.x - 1 = b.x and w.y - 1= b.y) 
     )
     where b.id is null
) as t

这不会像你定义的那样处理边界情况(x或y上的+/- 5),至少不是我理解你的表的方式,但你可以添加额外的OR和AND语句你的“开启”条件。

另外,我没有方便的表或数据库连接,因此未进行测试。可能存在一些小错误,但它们应该很容易修复。

修改: 我才意识到我可能会混淆你想要的空间。这有点令人困惑,因为我们没有看到您正在使用的表格。

经过一番思考之后,我认为你很可能想要一个条件,你在ON子句中做了类似的事情(我现在把+/-换成了建筑物的位置,而不是坐标):

(b.x + 1 = v.x and b.y + 1= w.y) OR
(b.x + 1 = v.x and b.y = w.y) OR
(b.x + 1 = v.x and b.y - 1= w.y) OR
(b.x = v.x     and b.y + 1= w.y) OR
(b.x = v.x     and b.y = w.y) OR
(b.x = v.x     and b.y - 1= w.y) OR
(b.x - 1 = v.x and b.y + 1= w.y) OR
(b.x - 1 = v.x and b.y = w.y) OR
(b.x - 1 = v.x and b.y - 1= w.y)