2013-06-06 4 views
1

Существуют ли какие-либо логические операторы короткого замыкания (в частности, короткое замыкание AND и короткое замыкание OR), которые я могу использовать в предложении WHERE в MySQL 5.5? Если нет, то каковы альтернативы?Операторы оценки короткого замыкания

Абстрактный взгляд на мою проблему, наряду с объяснением того, почему мне это нужно, можно найти на этой скрипке:

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); 
+0

Единственный способ, которым вы собираетесь это сделать, это использовать T-SQL, который я думаю. Если вы пишете запрос, который запрашивает ВСЕ магазины, тогда вы будете долго ждать, но с T-SQL вы можете установить переменные и флаги и т. Д., Чтобы вырваться из цикла, который итеративно выполняет меньшую часть запроса (т. Е. Хранилище запросов в хранилище) как только совпадение найдено. –

+0

Готов поспорить, что он прекратит оценивать выражение 'OR', как только один из совпадений, если ни одно из выражений не имеет побочных эффектов. – Barmar

+0

@Barmar: Это не так, к сожалению, как вы можете видеть в скрипке, строки, которые удовлетворяют другим условиям OR, также возвращаются. –

ответ

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; 
+0

Спасибо за ваш ответ, к сожалению, это вернет только одну книгу, пока нам действительно нужно получить результаты для всех книг. –

+0

... err, но в вашем вопросе говорится, что «остановитесь, как только у нас получится». Если вам нужно получить все результаты, вам придется пересекать все строки @ChristianKiewiet –

+1

Я думаю, что он означает «остановить проверку столбцов в' OR', как только один будет удовлетворен ». – Barmar

Смежные вопросы