請注意,以下問題是專門針對MySQL。使用複雜篩選優化SQL查詢
想象的表中調用Cars
結構如下(我們可以忽略缺乏適當的鍵約束等,因爲它是不相關的我的問題):
CREATE TABLE Cars
(
id Integer,
maker_id Integer,
status_id Integer,
notes Varchar(100)
);
現在想象加載一些測試數據是這樣的:
INSERT INTO Cars
(id, maker_id, status_id, notes)
VALUES
(1, 1001, 0, 'test1'),
(2, 1001, 0, 'test2'),
(3, 1001, 0, 'test3'),
(4, 1002, 0, 'test4'),
(5, 1002, 0, 'test5'),
(6, 1002, 1, 'test6'),
(7, 1002, 1, 'test7'),
(8, 1002, 2, 'test8'),
(9, 1003, 3, 'test9'),
(10, 1003, 3, 'test10'),
(11, 1003, 4, 'test11'),
(12, 1003, 4, 'test12'),
(13, 1003, 5, 'test13'),
(14, 1003, 5, 'test14')
有14個記錄,在maker_id
3個DISTINCT
值(1001,1002,1003),和6個DISTINCT
值在status_id
(0,1,2,3,4,5)。
現在,想象一下采取DISTINCT
雙(maker_id
,status_id
)。
SELECT DISTINCT maker_id, status_id FROM Cars;
以下是在SQL小提琴一個示例的鏈接:http://sqlfiddle.com/#!9/cb1c7/2
這導致以下記錄(maker_id
,status_id
):
- (1001,0)
- ( 1002,0)
- (1002,1)
- (1002,2)
- (1003,3)
- (1003,4)
- (1003,5)
的爲我需要返回邏輯如下:
如果一個給定maker_id
值(例如1001)對於其對應的DISTINCT
(maker_id
,status_id
)對只有1個不同記錄,只需將其返回即可。在這個例子中:(1001,0)。
如果給定maker_id
值具有大於1對於其相應DISTINCT
(maker_id
,status_id
)對不同的記錄,返回所有他們的除所述一個與status_id
值的0。在本例中:(1002 ,1),(1002,2),(1003,3),(1003,4)和(1003,5)。
請注意,我們遺漏了(1002,0)。
任何人都可以想到一個conciser /更有效率(就運行時而言)寫這個查詢的方式嗎?在現實世界中,我的桌子有數百萬條記錄。
我想出了以下內容:
SELECT
subq.maker_id,
subq.status_id
FROM
(
SELECT DISTINCT
maker_id,
status_id,
(SELECT COUNT(*) FROM Cars WHERE maker_id = c.maker_id AND status_id != 0 GROUP BY maker_id) AS counter
FROM Cars AS c
) AS subq
WHERE
subq.counter IS NULL
OR (subq.counter IS NOT NULL AND subq.status_id != 0)
;
這裏是SQL小提琴一個例子:http://sqlfiddle.com/#!9/cb1c7/3
1.你有什麼指標? 2.首先分別選擇兩個案例。 – philipxy
@philipxy感謝您的回覆! 1)我們沒有indeces(並且不能創建它們)2)你的意思是做兩個子查詢和UNION結果嗎? – cuddlyhugbear
兩種選擇和UNION是我現在唯一能想到的其他方式...... –