2

MySQL 5.5 の句で使用できる短絡論理演算子 (特に short-circuitANDと short-circuit OR) はありますか? WHEREない場合、代替手段は何ですか?

私の問題の抽象的な見方と、これが必要な理由についての説明は、このフィドルで見つけることができます:

http://sqlfiddle.com/#!2/97fd1/3

実際には、私たちは何百もの国の何千もの都市にある何百万もの書店で何百万冊もの本を見ています。そのため、送信するすべてのクエリで不要な情報を受け取るオーバーヘッドを受け入れることができず、問題を解決する方法を真剣に見つける必要があります。次の OR に進む前に、現在の条件を満たすすべての行があるとすぐに評価が停止します。

さらに情報が必要な場合はお知らせください。前もって感謝します。


リクエストに応じて、フィドルで使用されるスキーマは次のとおりです。

CREATE TABLE quantitycache (
  id INT AUTO_INCREMENT,
  quantity INT,
  book_id INT NOT NULL,
  bookstore_id INT NULL,
  city_id INT NULL,
  country_id INT NULL,
  PRIMARY KEY (id)
);

いくつかのサンプルデータと同様に:

INSERT INTO quantitycache 
     (quantity, book_id, bookstore_id, city_id, country_id)
VALUES
     (5,        1,       1,            NULL,    NULL),
     (100,      2,       1,            NULL,    NULL),
     (7,        1,       2,            NULL,    NULL),
     (12,       1,       NULL,         1,       NULL),
     (12,       1,       NULL,         NULL,    1),
     (100,      2,       NULL,         1,       NULL),
     (100,      2,       NULL,         NULL,    1),
     (200,      3,       NULL,         1,       NULL),
     (250,      3,       NULL,         NULL,    1);
4

1 に答える 1

1

クエリは命令的に実行されないことに注意してください。作成したクエリは複数のスレッドで実行される可能性があるため、where 句の短絡演算子によって結果が 1 つだけになることはありません。

代わりに、LIMIT句を使用して最初の行のみを返します。

SELECT * FROM quantitycache
WHERE bookstore_id = 1 OR city_id = 1 OR country_id = 1
ORDER BY bookstore_id IS NULL ASC,
         city_id IS NULL ASC,
         country_id IS NULL ASC
LIMIT 1;

結果セット内のすべての書籍に最適な一致を取得するには、結果を一時テーブルに保存し、最適な結果を見つけてから、興味深いフィールドを返します。

CREATE TEMPORARY TABLE results (id int, book_id int, match_rank int);

INSERT INTO results (id, book_id, match_rank)
SELECT id, book_id, 
    -- this assumes that lower numbers are better
    CASE WHEN Bookstore_ID is not null then 1 
         WHEN City_ID is not null then 2 
         ELSE 3 END as match_rank
FROM quantitycache
WHERE bookstore_id = 1 OR city_id = 1 OR country_id = 1;

Select * 
from (
    select book_id, MIN(match_rank) as best_rank 
    from results 
    group by book_id
) as r
inner join results as rid 
    on r.book_id = rid.book_id 
    and rid.match_rank = r.best_rank
inner join quantitycache as q on q.id = rid.id;

DROP TABLE results;
于 2013-06-06T18:51:25.243 に答える