2

我可以在 MySQL 5.5 的子句中使用任何短路逻辑运算符(特别是 short-circuitAND和 short-circuit )吗?如果没有,有什么替代方案?ORWHERE

我的问题的抽象视图以及我为什么需要这个的解释可以在这个小提琴中找到:

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 子句中的短路运算符不会只产生一个结果。

相反,使用该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 回答