Mysql按问题排序

时间:2013-04-08 13:21:02

标签: mysql sql sql-order-by

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

在数据库中,我编写了地图的每个图块,即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值,每个坐标都有双输入。哈文没见过。

1 个答案:

答案 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个单位