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

編集:
double 値を無視し、各座標に double 入力がありました。見たことがない。

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) が与えられたとき、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。これは、画面に表示する行の順序付けに最初に関心があるためです。次のコードは (最終的に) ( 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 に答える