我的代码中有这个SQL,并且子查询的重复使我担心这不是有效写入的。
我的数据库有一个features
,responses
和participants
的表格。参与者为每个特征给出评级(D,P,B,I,R,Q之一)。
SELECT f.id, f.name,
(SELECT COUNT(r.id) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS nr_r,
(SELECT SUM(r.is_D) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS is_D,
(SELECT SUM(r.is_P) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS is_P,
(SELECT SUM(r.is_B) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS is_B,
(SELECT SUM(r.is_I) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS is_I,
(SELECT SUM(r.is_R) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS is_R,
(SELECT SUM(r.is_Q) FROM responses r LEFT JOIN participants p ON r.id_participant = p.id WHERE p.is_ignored IS NULL AND r.is_deleted IS NULL AND r.id_feature = f.id AND p.category LIKE :p_category) AS is_Q,
(SELECT (is_D + is_P)/(is_D + is_P + is_B + is_I)) as yay,
(SELECT (is_P + is_B)/(is_D + is_P + is_B + is_I)) as boo
FROM features f
WHERE f.is_deleted IS NULL AND f.id_survey=:id_project
ORDER BY f.id ASC;
该查询的输出是一个总计表,类似于
577 App registration 989 36 21 38 201 42 6 0.1926 0.1993
578 Login PIN 989 279 118 137 394 41 20 0.4278 0.2748
579 Manage all services 989 287 207 127 331 23 14 0.5189 0.3508
580 Rewards 989 344 157 64 386 19 19 0.5268 0.2324
581 Offers 989 226 93 37 542 72 19 0.3552 0.1448
查询目前需要4.4387秒来运行具有989个参与者的数据集,14个特征(因此有13,846个个体评级)。很确定这很臭。
是否有更有效的方式来编写该查询?
这是GROUP BY有用的东西吗?
答案 0 :(得分:1)
如果我理解你的查询,你在每个子查询中都有相同的谓词,然后你可以轻松地用连接替换所有子选择并执行分组。聚合物(yay和boo)的计算在外层计算:
SELECT id, name, nr_r, is_D, ...
, (is_D + is_P)/(is_D + is_P + is_B + is_I) yay
, (is_P + is_B)/(is_D + is_P + is_B + is_I) boo
FROM (
SELECT f.id, f.name
, count(r.id) AS nr_r
, sum(r.is_D) as is_D
, ...
FROM features f
LEFT JOIN responses r
ON r.id_feature = f.id
AND r.is_deleted IS NULL
LEFT JOIN participants p
ON r.id_participant = p.id
AND p.is_ignored IS NULL
AND p.category LIKE :p_category
WHERE f.is_deleted IS NULL
AND f.id_survey=:id_project
GROUP BY f.id, f.name
) AS T
ORDER BY ...