我有以下設置:優化SQL查詢反覆case語句
CREATE TABLE table_name
(
perf_id INT,
build_id INT,
series_id INT,
client_id INT,
measurement INT
);
INSERT INTO table_name VALUES (1, 1, 1, 1, 10);
INSERT INTO table_name VALUES (2, 1, 2, 1, 15);
INSERT INTO table_name VALUES (3, 2, 1, 1, 10);
INSERT INTO table_name VALUES (4, 2, 2, 1, 15);
INSERT INTO table_name VALUES (5, 2, 2, 1, 20);
INSERT INTO table_name VALUES (6, 3, 1, 1, 10);
INSERT INTO table_name VALUES (7, 3, 2, 1, 20);
然後我用下面的查詢這樣的:
SELECT
build_id,
CONCAT(
MIN(CASE WHEN series_id IN (1) THEN measurement ELSE NULL END),
';',
AVG(CASE WHEN series_id IN (1) THEN measurement ELSE NULL END),
';',
MAX(CASE WHEN series_id IN (1) THEN measurement ELSE NULL END)
),
CONCAT(
MIN(CASE WHEN series_id IN (2) THEN measurement ELSE NULL END),
';',
AVG(CASE WHEN series_id IN (2) THEN measurement ELSE NULL END),
';',
MAX(CASE WHEN series_id IN (2) THEN measurement ELSE NULL END)
)
FROM table_name GROUP BY build_id;
您可以在這裏找到一個sqlFiddle http://sqlfiddle.com/#!9/efef8/17
我想優化我的查詢,主要是爲了減少重複的代碼。我將從PHP調用此函數,併爲IN運算符綁定值。
我想通功能可取代的重複代碼批量:
CREATE FUNCTION data(s INT)
RETURNS VARCHAR(50)
RETURN CONCAT(
MIN(CASE WHEN series_id IN (s) THEN measurement ELSE NULL END),
';',
AVG(CASE WHEN series_id IN (s) THEN measurement ELSE NULL END),
';',
MAX(CASE WHEN series_id IN (s) THEN measurement ELSE NULL END)
)
但這種抱怨不恰當地使用聚合函數的。我也不確定如何傳入IN運算符的數組。
NB:
的毗連運算似乎並沒有對SQLFiddle工作,但確實在我的機器上。我不知道我是否弄亂了一些語法?
列數將是可變的。
我也將在GROUP BY之前控制WHERE語句,但是我有這個工作,我只是不想重複我的concat一百萬次。
SQL沒有數組。你可以創建一個臨時表,然後使用'WHEN series_id IN(SELECT id FROM temptable)' – Barmar
但是你不能在函數中使用像'MIN'和'AVG'這樣的聚合函數,因爲它們在一個查詢,而不是個別值。 – Barmar
我想這個術語數組來自於我將綁定到它的PHP變量。我認爲我不能將一個像「(1)」或「(1,2,3,4,5)」這樣的可變長度的「數組」傳遞給一個函數?我可以將表格傳遞給函數嗎?並創建這個臨時表,然後傳入? – Deoxyribonucleic