在mysql中的一個查詢中做到這一點的最佳方法是什麼?另一個WHERE子句,如果沒有結果
SELECT * FROM products WHERE language = 1
如果沒有結果
SELECT * FROM products WHERE language = 2 AND country = 1
如果沒有結果
SELECT * FROM products WHERE language = 2 AND country = 2
在mysql中的一個查詢中做到這一點的最佳方法是什麼?另一個WHERE子句,如果沒有結果
SELECT * FROM products WHERE language = 1
如果沒有結果
SELECT * FROM products WHERE language = 2 AND country = 1
如果沒有結果
SELECT * FROM products WHERE language = 2 AND country = 2
我已經編輯它使其工作,但它不再優雅。
原來的(沒有最後一個也沒有)存在缺陷。
原來,這並不像我想象的那麼聰明。見下面的評論。如果第一個和第三個查詢返回數據,它將失敗。如果你只有一個聯盟,但不是兩個或更多聯盟,它確實有效。
這是很容易在MySQL:
select SQL_CALC_FOUND_ROWS * from products where language = 1
union
SELECT * FROM products WHERE language = 2 AND country = 1 and found_rows()=0
union
SELECT * FROM products WHERE language = 2 AND country = 2 and found_rows()=0
AND not exists(select * from products where language = 1)
見FOUND_ROWS的討論()和SQL_CALC_FOUND_ROWS這裏: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows
的MySQL缺乏的功能,以使這一個去
例子:DENSE_RANK
窗函數,或TOP..WITH TIES
因此,而不使用臨時表或IF語句(無論如何需要MySQL中的存儲過程),然後在客戶端上將其過濾爲最低優先級值。也就是說,消耗行直到數值發生變化
SELECT *, 1 AS priority FROM products WHERE language = 1
UNION ALL
SELECT *, 2 AS priority FROM products WHERE language = 2 AND country = 1
UNION ALL
SELECT *, 3 AS priority FROM products WHERE language = 2 AND country = 2
ORDER BY priority;
即使不理想,這也會消除往返於MySQL服務器的往返行程。它也避免了重新評估EXISTS子句中的先前SELECTs
你可以做一個單一的選擇,如果你評估優先級作爲一種情況下的條件 - 類似'case語言1時1當2則語言+國家其他4結束'。 – 2013-04-24 14:41:08
您可以使用類似以下內容:(編輯使用exists並根據評論限制)。
(
SELECT * FROM products WHERE language = 1
)
UNION
(
SELECT * FROM products WHERE language = 2 AND country = 1
AND NOT EXISTS(SELECT count(*) FROM products WHERE language = 1 limit 1)
)
UNION
(
SELECT * FROM products WHERE language = 2 AND country = 2
AND NOT EXISTS(SELECT count(*) FROM products WHERE language = 2 AND country = 1 limit 1)
AND NOT EXISTS(SELECT count(*) FROM products WHERE language = 1 limit 1)
)
您使用嵌套查詢和計數(*)檢查以前的查詢是否爲NULL。
使用不存在可能比檢查0計數好。 – 2013-04-24 14:17:32
@ShawnBalestracci將這些子查詢(COUNT或EXISTS - 無所謂)在每一行上重新執行?也許離開加入+檢查空將是更好的方法? – 2013-04-24 14:19:24
我有一種強烈的感覺,優化器計算出最佳分支,並僅對其進行一次預先計算。這就是SQL引擎的原因:)。 – 2013-04-24 14:21:57
嘗試:
select p.*
from (select min(language) minlang, min(country) minctry
from products where language = 1 or
(language = 2 and country in (1,2))) c
join products p
on p.language = c.minlang and (c.minlang=1 or p.country=c.minctry)
似乎有沒有什麼好辦法,如果可能的話,你最好把它變成一個過程,無論是填充臨時表或返回RowSet對象的客戶端
如何永遠如果沒有可能,你似乎有限制二級和三級查詢:
SELECT * FROM products WHERE language = 1
UNION ALL
SELECT * FROM products WHERE language = 2 AND country = 1
AND NOT EXISTS (SELECT * FROM products WHERE language = 1)
UNION ALL
SELECT * FROM products WHERE language = 2 AND country = 2
AND NOT EXISTS (SELECT * FROM products WHERE language = 1 OR (language = 2 AND country = 1))
但這只是醜陋和緩慢。
也許與IS NULL左加入會比不存在,雖然
什麼專欄是'*'? – Kermit 2013-04-24 14:00:38
這不是MySQL中的一個查詢,不幸的是:您期望從中得到什麼 – gbn 2013-04-24 14:02:12
我認爲您可以通過ORDER – lvil 2013-04-24 14:03:02