好的,我在订购方面遇到了一些困难。这是我需要解决的问题:
在数据库中,我编写了地图的每个图块,即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的所有切片。
但是,它并没有按照我想要的方式对它们进行排序。基本上,输出必须类似于this。
但这是我得到的最接近的。 http://prntscr.com/zqjd7
修改:
忽略double值,每个坐标都有双输入。哈文没见过。
答案 0 :(得分: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),我们将通过约束D(P,Q) = SQRT( (x-m)² + (y-n)² )
知道到固定点Q(x,y)的距离。尽管它必须小于(或等于)你想要的半径(= 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)
放在0
和@var1
的位置来选择来源@var2
。
<强> [更新] 强>
嗯...在回答之前测试代码总是一个好主意。实际上我应该建议首先按y
订购,因为我们首先要关心在屏幕上显示排序行。以下代码(最终)经过测试(在test
DB上);我的最后建议是创建以下索引(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个单位