2013-06-19 3 views
14

Он чувствует себя довольно просто в чем угодно, кроме MySQL.IF Условие Выполнение запроса, другое Выполнение другого запроса

В основном мне нужно переключить какой тип индекса я использую вместе с несколькими другими условиями, основанными на том, сколько результатов возвращает определенный термин.

Что-то эффект:

IF (SELECT COUNT(*) FROM table WHERE term LIKE "term") > 4000 
    EXECUTE QUERY A 
ELSE 
    EXECUTE QUERY B 

Возможно ли это в заявлении MySQL?

РЕДАКТИРОВАТЬ:

Запрос А:

SELECT id 
FROM table_a 
FORCE INDEX(id) 
JOIN table_b ON table_a.id = table_b.id 
WHERE term LIKE "term" 
ORDER BY date 
LIMIT 100; 

Запрос Б:

SELECT id 
FROM table_a 
FORCE INDEX(term) 
JOIN table_b ON table_a.id = table_b.id 
WHERE term LIKE "term" 
GROUP BY term # These lines would be included for a few conditions not mentioned above.. but are necessary 
HAVING COUNT = 1 # same... 
ORDER BY date 
LIMIT 100; 

Причина переключателя запроса я получаю совершенно разные времена результата, основанные на популярность «термина».

+2

Что такое 'QUERY A' и' QUERY B'? SQL обычно разрешает эту ситуацию обрабатывать с помощью объявления 'WHERE', но мы не можем сказать, если мы не знаем, связаны ли A & B. –

+1

... В противном случае MySQL допускает использование логики управления потоком в функциях, триггерах и хранимых процедурах, а не в обычных запросах. –

+0

В теории - да (с помощью оператора 'CASE' и объединения), но это зависит от того, совпадает ли количество полей и записей в обоих запросах.Вы должны отправить эти два вместе с тестовыми данными, чтобы мы могли ответить. –

ответ

16

EDIT: То, что я сказал о ниже требующих хранимой процедуры, это не так. Попробуйте это:

SELECT CASE WHEN ((SELECT COUNT(*) FROM table WHERE term LIKE "term") > 4000) 
    THEN <QUERY A> 
    ELSE <QUERY B> 
END 

Это, на самом деле, выражение случая, и она отлично работает за пределами хранимой процедуры :-)

Например:

mysql> SELECT CASE WHEN (5 > 4) THEN (SELECT 'foo') ELSE (SELECT 'bar') END; 
+---------------------------------------------------------------------+ 
| CASE WHEN (5 > 4) THEN (SELECT 'foo') ELSE (SELECT 'bar') END | 
+---------------------------------------------------------------------+ 
| foo                 | 
+---------------------------------------------------------------------+ 
1 row in set (0.01 sec) 

mysql> SELECT CASE WHEN (3 > 4) THEN (SELECT 'foo') ELSE (SELECT 'bar') END; 
+---------------------------------------------------------------------+ 
| CASE WHEN (3 > 4) THEN (SELECT 'foo') ELSE (SELECT 'bar') END | 
+---------------------------------------------------------------------+ 
| bar                 | 
+---------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

Старого ответ ниже исторического проценты, поскольку он уже собирает upvotes:

Вы можете использовать нижеследующее, я думаю, но только внутри хранимой процедуры:

CASE (SELECT COUNT(*) FROM table WHERE term LIKE "term") > 4000 
    WHEN 1 THEN <QUERY A> 
    ELSE <QUERY B> 
END CASE 

Это CASE заявление, в отличие от выражения CASE ... https://dev.mysql.com/doc/refman/5.0/en/case.html имеет более окровавленные детали.

На самом деле, я подозреваю, что если вы хотите выполнить разные запросы условно, вам нужно будет посмотреть на хранимые процедуры - я могу ошибаться, но это мое чувство кишки в этот момент. Если вы можете это сделать, это, вероятно, будет с выражениями CASE!

Последнее редактирование: в любом примере реального мира я бы, вероятно, выполнил условный бит в своем приложении и просто передал SQL (или ORM, который бы сгенерировал мой SQL), как только я решил, искать.

+1

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

4

Try:

select coalesce(i.id, t.id) id 
from (SELECT COUNT(*) countterm FROM table WHERE term LIKE "term") c 
left join 
    (SELECT id, date 
     FROM table_a 
     FORCE INDEX(id) 
     JOIN table_b ON table_a.id = table_b.id 
     WHERE term LIKE "term") i on countterm > 4000 
left join 
    (SELECT id, date 
     FROM table_a 
     FORCE INDEX(term) 
     JOIN table_b ON table_a.id = table_b.id 
     WHERE term LIKE "term" 
     GROUP BY term 
     HAVING COUNT = 1) t on countterm <= 4000 
ORDER BY coalesce(i.date, t.date) 
LIMIT 100; 
+2

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

+0

@Bohemian: выполнит ли он суб-запрос, если условие 'join ... on' (to the main query) неверно? –

+1

Я бы так подумал, потому что условие ON - это предложение mini where - фильтр - для соединенных строк, а ложность этого условия не может быть оптимизирована (никто не знает заранее, что он будет ложным). Я мог ошибаться ... – Bohemian

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