2013-06-19 158 views
14

除了MySQL之外,其他任何事情都很簡單。如果條件執行查詢,否則執行其他查詢

基本上我需要根據特定術語返回的結果數來切換我正在使用的索引類型以及其他一些條件。

某事的效果:

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; 

查詢B:

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

編輯:我說低於約需要一個存儲過程是不正確的。試試這個:

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

這的確是一個CASE表達式,它存儲的過程之外的正常工作:-)

例如:

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) 

老回答下面的歷史興趣,因爲它已經收集起來:

你可以使用下面的我認爲,但只在一個存儲過程:

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(或者生成我的SQL的ORM)搜索。

+1

您可能還應該提及,只有當查詢只返回1行時,這才起作用。否則,你會得到一個錯誤,指出子查詢返回多於一行。 – fancyPants

4

嘗試:

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」(對於主要查詢)條件爲false,它會真正執行子查詢嗎? –

+1

我會這樣認爲的,因爲ON條件是一個mini where子句 - 一個過濾器 - 用於連接的行,並且條件的錯誤不能被優化出來(無法事先知道它將是錯誤的)。我可能是錯的...... – Bohemian