あなたの問題は 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) が与えられたとき、acert によって定点 Q (x,y) までの距離がわかりD(P,Q) = SQRT( (x-m)² + (y-n)² )
ます。必要な半径 (= 3) よりも小さい (または等しい) 必要がある限り、SQRT( (x-m)² + (y-n)² ) <= 3
両方(x-m)² + (y-n)² <= 3²
の項をその 2 乗に累乗することになります。
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 単位の範囲で返します