我正在開發項目來管理現場項目關鍵績效指標(KPI)的提交。每份提交文件都附有績效評估標準(PMs),這些都是在現場提交時提交的。需要幫助減少非常大的MySQL查詢
PM根據完成程度由用戶給出分數。我現在正在製作一份使用所有這些數據的報告。我有一個可行的查詢,但它非常龐大和繁瑣。我試圖找到一種簡化它的方法。
我有一個查詢生成KPI列表。有了這個清單,我就可以應用一些子查詢和簡單的數學運算來產生那個時期的「分數」。
有13個時期。分數是根據當年完成提交的業績衡量標準計算得出的。有兩種類型的提交「面板」和「程序」。
需要爲每個期間的兩種提交類型計算得分。然後取這些分數的平均值並計算最終分數。
最終得分稱爲疼痛/增益指標。我們計算得分,除以100,然後乘以0.3。如果數字小於1,那麼我們從疼痛/增益中分別減去1,如果數字大於0,我們加1。
週期1是不同的,因爲我們只需要計算程序提交,見下圖:
週期然而1
(
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016' //current year
AND sub.state = '2' //state 2 is complete
AND sub.period = '1'
AND pm.kpi_id = kpi.id
) AS p1
其他時段內需要根據雙方提交類型比分:
PERIOD 2 - 12
CASE
WHEN
(
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3 < 0 THEN
1- ROUND((
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3, 2)
WHEN
(
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3 > 0 THEN
1+ ROUND((
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3, 2)
END
END AS p2
此,目前正在重複進行的剩餘週期。我得到的數據很好,但查詢是巨大的和醜陋的。最重要的是,我希望在結果的末尾有一列爲所有13個時段的每個KPI創建平均分數。我知道我無法引用由其別名創建的列,所以我現在必須重複子查詢以獲得此分數。
無論如何,我可以使這個查詢更有效率或循環週期2-13?
的結果完整查詢低於:
完整的查詢UP TO週期2
SELECT
kra.id AS id,
kra.kra_name AS name,
kra.panel_weighting AS panel_weighting,
kra.programme_weighting AS programme_weighting,
kpi.id AS id,
kpi.kpi_name AS name,
kpi.panel_weighting AS panel_weighting,
kpi.programme_weighting AS programme_weighting,
(
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '1'
AND pm.kpi_id = kpi.id
) AS p1,
CASE
WHEN (
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
) IS NULL
AND
(
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
) IS NULL
THEN NULL
ELSE
CASE
WHEN
(
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3 < 0 THEN
1- ROUND((
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3, 2)
WHEN
(
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3 > 0 THEN
1+ ROUND((
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.period = '2'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.panel = 'panel'
AND pm.kpi_id = kpi.id
), 0) +
IFNULL((
SELECT
ROUND(AVG(sp.progress), 2)
FROM `submissions` AS sub
LEFT JOIN `sub_performancemeasures` sp ON sp.sub_id = sub.id
LEFT JOIN `performance_measures` pm ON pm.id = sp.pm_id
WHERE sub.programme = 'programme'
AND sub.submission_year = '2015/2016'
AND sub.state = '2'
AND sub.period = '2'
AND pm.kpi_id = kpi.id
), 0)/2)/100 * 0.3, 2)
END
END AS p2
FROM `kpis` kpi
LEFT JOIN `key_reporting_areas` kra ON kra.id = kpi.kra_id
GROUP BY kpi.id
如果您喜歡,請考慮遵循以下簡單的兩步式操作:1.如果您尚未這樣做,請提供適當的CREATE和INSERT語句(和/或sqlfiddle),以便我們可以更輕鬆地複製問題。 2。如果您尚未這樣做,請提供與步驟1中提供的信息相對應的所需結果集。 – Strawberry
@Strawberry,能不能不斷髮布有關DDL/Sample/SqlFiddle的信息。我在過去的10天裏見過大約十幾次。如果你不能弄清楚或者在心理上理解它,不要。 – DRapp