0

好的,我在订购时遇到了一些困难。这是我需要解决的问题:

在数据库中,我已经编写了地图的每个图块,即 101 x 101 大。该表有 3 列(ID、x、y),现在我必须选择一些半径中的所有图块。例如,我使用了这个查询:

SELECT * 
FROM tile 
WHERE ((x >= -3 AND x <= 3) 
AND (y >= -3 AND y <= 3)) 
ORDER BY x ASC, y DESC;

此查询暂时选择给定坐标 (0|0) 半径为 3 的所有图块。

但是,它并没有按照我想要的方式对它们进行排序。基本上,输出必须是这样

但这是我得到的最接近的。 http://prntscr.com/zqjd7

编辑
忽略双值,每个坐标都有双输入。没见过。

4

1 回答 1

1

您的问题似乎与 ASC / DESC 修饰符有关。
但是既然我们在这里,你不喜欢使用距离公式吗?附近的东西

SELECT x, y FROM tile WHERE
(
  POW(x-@var1, 2) + POW(y-@var2, 2) <= POW(3, 2)
)
ORDER BY x DESC, y ASC;

在这里,给定一个点 P (m,n),我们将通过 acerting 知道到固定点 Q (x,y) 的距离D(P,Q) = SQRT( (x-m)² + (y-n)² )。尽管它必须小于(或等于)您所需的半径 (= 3),但我们有SQRT( (x-m)² + (y-n)² ) <= 3或更好,(x-m)² + (y-n)² <= 3²将这两项都提高到它的平方幂。

SQL 语言讲,我们写POW(x-m, 2) + POW(y-n, 2) <= POW(3, 2),愿意说和之间的距离(x,y)(m,n)大于等于3的。

关于@var,这是您输入输入值的地方。更具体地说,它们是会话变量,但您并不想用它来执行选择;只需将它们替换为您想要的任何数字,例如,您可以(0,0)通过放置0and@var1来选择原点@var2

[更新]
嗯......在回答之前测试你的代码总是一个好主意。事实上,我应该建议先按y排序,因为我们首先关心要在屏幕上显示的排序行。以下代码(最终)经过测试(在testDB 上);我的最后一个建议是创建以下索引(index_y_x):

USE `test` ;

CREATE TABLE IF NOT EXISTS `test`.`tile` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT ,
  `x` INT(11) NULL DEFAULT 0 ,
  `y` INT(11) NULL DEFAULT 0 ,
  PRIMARY KEY (`id`) ,
  INDEX `index_y_x` (`y` DESC, `x` ASC) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

INSERT tile (x,y) VALUES
(-2,-2),(-2, -1),(-2, 0),(-2, 1),(-2, 2),
(-1,-2),(-1, -1),(-1, 0),(-1, 1),(-1, 2),
(0,-2), (0, -1), (0, 0), (0, 1), (0, 2),
(1,-2), (1, -1), (1, 0), (1, 1), (1, 2),
(2,-2), (2, -1), (2, 0), (2, 1), (2, 2);

SELECT x, y FROM tile
WHERE POW(x-3, 2) + POW(y-3, 2) <= POW(3, 2)
ORDER BY y DESC, x ASC;

这将返回点 (3,3) 附近的项目,范围为 3 个单位

于 2013-04-08T13:44:42.723 回答