我有以下设置:
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:
concat运算符似乎不适用于SQLFiddle,但在我的机器上运行。我不知道我是否搞砸了一些语法?
列数可变。
我也将在GROUP BY之前控制一个WHERE语句,但是我有这个工作,我只是不想重复我的concat一百万次。
答案 0 :(得分:2)
您需要在功能中进行选择。试试这个:
DELIMITER $$
create FUNCTION data(s INT, id int)
RETURNS VARCHAR(50)
BEGIN
DECLARE res VARCHAR(50);
SET res = (SELECT 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)
)
from table_name
where build_id = id);
RETURN res;
END$$
select
t.build_id
, data(1, t.build_id)
, data(2, t.build_id)
from table_name t
group by t.build_id
答案 1 :(得分:1)
如果您不关心值为0
的行:
SELECT build_id,
CONCAT_WS(';', MIN(measurement), AVG(measurement), MAX(measurement)),
FROM table_name
WHERE series_id = 2
GROUP BY build_id;
获取其他行:
SELECT build_id,
CONCAT_WS(';', MIN(measurement), AVG(measurement), MAX(measurement)),
FROM table_name
WHERE series_id = 2
GROUP BY build_id
UNION ALL
SELECT build_id, ''
FROM table_name
GROUP BY build_id
HAVING MAX(series_id = 2) = 0;