diff --git a/grafana/dashboards/DORA.json b/grafana/dashboards/DORA.json index 21046947201..b876191c16f 100644 --- a/grafana/dashboards/DORA.json +++ b/grafana/dashboards/DORA.json @@ -211,7 +211,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n),\n\n_metric_deployment_frequency as (\n\tSELECT \n\t 'Deployment frequency' as metric, \n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per day and once per week(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per week and once per month(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN 'Fewer than once per month(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per day and once per month(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN 'Between once per month and once every 6 months(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN 'Fewer than once per six months(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n),\n\n-- Metric 2: median lead time for changes\n_pr_stats as (\n-- get the cycle time of PRs deployed by the deployments finished in the selected period\n\tSELECT\n\t\tdistinct pr.id,\n\t\tppm.pr_cycle_time\n\tFROM\n\t\tpull_requests pr \n\t\tjoin project_pr_metrics ppm on ppm.id = pr.id\n\t\tjoin project_mapping pm on pr.base_repo_id = pm.row_id and pm.`table` = 'repos'\n\t\tjoin cicd_deployment_commits cdc on ppm.deployment_commit_id = cdc.id\n\tWHERE\n\t pm.project_name in (${project}) \n\t\tand pr.merged_date is not null\n\t\tand ppm.pr_cycle_time is not null\n\t\tand $__timeFilter(cdc.finished_date)\n),\n\n_median_change_lead_time_ranks as(\n\tSELECT *, percent_rank() over(order by pr_cycle_time) as ranks\n\tFROM _pr_stats\n),\n\n_median_change_lead_time as(\n-- use median PR cycle time as the median change lead time\n\tSELECT max(pr_cycle_time) as median_change_lead_time\n\tFROM _median_change_lead_time_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_change_lead_time as (\n\tSELECT \n\t\t'Lead time for changes' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 24 * 60 THEN \"Less than one day(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Between one day and one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 30 * 24 * 60 THEN \"Between one week and one month(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 30 * 24 * 60 THEN \"More than one month(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Less than one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 180 * 24 * 60 THEN \"Between one week and six months(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 180 * 24 * 60 THEN \"More than six months(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\nFROM _median_change_lead_time\n),\n\n-- Metric 3: change failure rate\n_deployments as (\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(cdc.finished_date) as deployment_finished_date\n\tFROM \n\t\tcicd_deployment_commits cdc\n\t\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n\tHAVING $__timeFilter(max(cdc.finished_date))\n),\n\n_failure_caused_by_deployments as (\n-- calculate the number of incidents caused by each deployment\n\tSELECT\n\t\td.deployment_id,\n\t\td.deployment_finished_date,\n\t\tcount(distinct case when i.type = 'INCIDENT' then d.deployment_id else null end) as has_incident\n\tFROM\n\t\t_deployments d\n\t\tleft join project_issue_metrics pim on d.deployment_id = pim.deployment_id\n\t\tleft join issues i on pim.id = i.id\n\tGROUP BY 1,2\n),\n\n_change_failure_rate as (\n\tSELECT \n\t\tcase \n\t\t\twhen count(deployment_id) is null then null\n\t\t\telse sum(has_incident)/count(deployment_id) end as change_failure_rate\n\tFROM\n\t\t_failure_caused_by_deployments\n),\n\n_is_collected_data as(\n\tSELECT\n CASE \n WHEN COUNT(i.id) = 0 AND COUNT(cdc.id) = 0 THEN 'No All'\n WHEN COUNT(i.id) = 0 THEN 'No Incidents' \n WHEN COUNT(cdc.id) = 0 THEN 'No Deployments'\n END AS is_collected\nFROM\n (SELECT 1) AS dummy\nLEFT JOIN\n issues i ON i.type = 'INCIDENT'\nLEFT JOIN\n cicd_deployment_commits cdc ON 1=1\n),\n\n_metric_cfr as (\n\tSELECT\n\t\t'Change failure rate' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t WHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .05 THEN \"0-5%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .10 THEN \"5%-10%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"10%-15%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .15 THEN \"> 15%(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"0-15%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .20 THEN \"16%-20%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .30 THEN \"21%-30%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .30 THEN \"> 30%(low)\" \n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM \n\t\t_change_failure_rate, _is_collected_data\n),\n\n-- ***** 2023 report ***** --\n-- Metric 4: Failed deployment recovery time\n_incidents_for_deployments as (\n SELECT\n i.id as incident_id,\n i.created_date as incident_create_date,\n i.resolution_date as incident_resolution_date,\n fd.deployment_id as caused_by_deployment,\n fd.deployment_finished_date,\n date_format(fd.deployment_finished_date,'%y/%m') as deployment_finished_month\n FROM\n issues i\n left join project_issue_metrics pim on i.id = pim.id\n join _deployments fd on pim.deployment_id = fd.deployment_id\n WHERE\n i.type = 'INCIDENT'\n and $__timeFilter(i.resolution_date)\n),\n\n_recovery_time_ranks as (\n SELECT *, percent_rank() over(order by TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as ranks\n FROM _incidents_for_deployments\n),\n\n_median_recovery_time as (\n SELECT max(TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as median_recovery_time\n FROM _recovery_time_ranks\n WHERE ranks <= 0.5\n),\n\n_metric_recovery_time_2023_report as(\n\tSELECT \n\t\"Failed deployment recovery time\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2023' THEN\n\t\tCASE\n\t\t\tWHEN median_recovery_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\tWHEN median_recovery_time < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\tWHEN median_recovery_time < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\tWHEN median_recovery_time >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\tEND\n\tEND AS median_recovery_time\n\tFROM \n\t_median_recovery_time\n),\n\n-- ***** 2021 report ***** --\n-- Metric 4: Median time to restore service \n_incidents as (\n-- get the incidents created within the selected time period in the top-right corner\n\tSELECT\n\t distinct i.id,\n\t\tcast(lead_time_minutes as signed) as lead_time_minutes\n\tFROM\n\t\tissues i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n\t join project_mapping pm on b.id = pm.row_id and pm.`table` = 'boards'\n\tWHERE\n\t pm.project_name in (${project})\n\t\tand i.type = 'INCIDENT'\n\t\tand $__timeFilter(i.created_date)\n),\n\n_median_mttr_ranks as(\n\tSELECT *, percent_rank() over(order by lead_time_minutes) as ranks\n\tFROM _incidents\n),\n\n_median_mttr as(\n\tSELECT max(lead_time_minutes) as median_time_to_resolve\n\tFROM _median_mttr_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_mttr_2021_report as(\n\tSELECT \n\t\"Time to restore service\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE\n\t\t\t\tWHEN median_time_to_resolve < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\tWHEN median_time_to_resolve < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\t\tWHEN median_time_to_resolve < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\t\tWHEN median_time_to_resolve >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\t\tEND\n\tEND AS median_time_to_resolve\n\tFROM \n\t\t_median_mttr\n),\n\n_metric_mrt_or_mm as(\n\tSELECT \n\tmetric,\n\tmedian_recovery_time AS value\n\tFROM \n\t_metric_recovery_time_2023_report\n\tWHERE \n\t('$dora_report') = '2023'\n\tUNION\n\tSELECT \n\tmetric,\n\tmedian_time_to_resolve AS value\n\tFROM \n\t_metric_mttr_2021_report\n\tWHERE \n\t('$dora_report') = '2021'\n),\n\n_final_results as (\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m1.metric as _metric, m1.value FROM dora_benchmarks db\n\tleft join _metric_deployment_frequency m1 on db.metric = m1.metric\n\tWHERE m1.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m2.metric as _metric, m2.value FROM dora_benchmarks db\n\tleft join _metric_change_lead_time m2 on db.metric = m2.metric\n\tWHERE m2.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m3.metric as _metric, m3.value FROM dora_benchmarks db\n\tleft join _metric_cfr m3 on db.metric = m3.metric\n\tWHERE m3.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m4.metric as _metric, m4.value FROM dora_benchmarks db\n\tleft join _metric_mrt_or_mm m4 on db.metric = m4.metric\n\tWHERE m4.metric is not null and db.dora_report = ('$dora_report')\n)\n\n\nSELECT \n\tmetric,\n\tcase when low = value then low else null end as low,\n\tcase when medium = value then medium else null end as medium,\n\tcase when high = value then high else null end as high,\n\tcase when elite = value then elite else null end as elite\nFROM _final_results\nORDER BY id", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n),\n\n_metric_deployment_frequency as (\n\tSELECT \n\t 'Deployment frequency' as metric, \n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per day and once per week(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per week and once per month(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN 'Fewer than once per month(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per day and once per month(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN 'Between once per month and once every 6 months(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN 'Fewer than once per six months(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n),\n\n-- Metric 2: median lead time for changes\n_pr_stats as (\n-- get the cycle time of PRs deployed by the deployments finished in the selected period\n\tSELECT\n\t\tdistinct pr.id,\n\t\tppm.pr_cycle_time\n\tFROM\n\t\tpull_requests pr \n\t\tjoin project_pr_metrics ppm on ppm.id = pr.id\n\t\tjoin project_mapping pm on pr.base_repo_id = pm.row_id and pm.`table` = 'repos'\n\t\tjoin cicd_deployment_commits cdc on ppm.deployment_commit_id = cdc.id\n\tWHERE\n\t pm.project_name in (${project}) \n\t\tand pr.merged_date is not null\n\t\tand ppm.pr_cycle_time is not null\n\t\tand $__timeFilter(cdc.finished_date)\n),\n\n_median_change_lead_time_ranks as(\n\tSELECT *, percent_rank() over(order by pr_cycle_time) as ranks\n\tFROM _pr_stats\n),\n\n_median_change_lead_time as(\n-- use median PR cycle time as the median change lead time\n\tSELECT max(pr_cycle_time) as median_change_lead_time\n\tFROM _median_change_lead_time_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_change_lead_time as (\n\tSELECT \n\t\t'Lead time for changes' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 24 * 60 THEN \"Less than one day(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Between one day and one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 30 * 24 * 60 THEN \"Between one week and one month(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 30 * 24 * 60 THEN \"More than one month(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Less than one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 180 * 24 * 60 THEN \"Between one week and six months(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 180 * 24 * 60 THEN \"More than six months(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\nFROM _median_change_lead_time\n),\n\n-- Metric 3: change failure rate\n_deployments as (\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(cdc.finished_date) as deployment_finished_date\n\tFROM \n\t\tcicd_deployment_commits cdc\n\t\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n\tHAVING $__timeFilter(max(cdc.finished_date))\n),\n\n_failure_caused_by_deployments as (\n-- calculate the number of incidents caused by each deployment\n\tSELECT\n\t\td.deployment_id,\n\t\td.deployment_finished_date,\n\t\tcount(distinct case when i.type = 'INCIDENT' then d.deployment_id else null end) as has_incident\n\tFROM\n\t\t_deployments d\n\t\tleft join project_issue_metrics pim on d.deployment_id = pim.deployment_id\n\t\tleft join issues i on pim.id = i.id\n\tGROUP BY 1,2\n),\n\n_change_failure_rate as (\n\tSELECT \n\t\tcase \n\t\t\twhen count(deployment_id) is null then null\n\t\t\telse sum(has_incident)/count(deployment_id) end as change_failure_rate\n\tFROM\n\t\t_failure_caused_by_deployments\n),\n\n_is_collected_data as(\n\tSELECT\n CASE \n WHEN COUNT(i.id) = 0 AND COUNT(cdc.id) = 0 THEN 'No All'\n WHEN COUNT(i.id) = 0 THEN 'No Incidents' \n WHEN COUNT(cdc.id) = 0 THEN 'No Deployments'\n END AS is_collected\nFROM\n (SELECT 1) AS dummy\nLEFT JOIN\n issues i ON i.type = 'INCIDENT'\nLEFT JOIN\n cicd_deployment_commits cdc ON 1=1\n),\n\n_metric_cfr as (\n\tSELECT\n\t\t'Change failure rate' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t WHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .05 THEN \"0-5%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .10 THEN \"5%-10%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"10%-15%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .15 THEN \"> 15%(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"0-15%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .20 THEN \"16%-20%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .30 THEN \"21%-30%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .30 THEN \"> 30%(low)\" \n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM \n\t\t_change_failure_rate, _is_collected_data\n),\n\n-- ***** 2023 report ***** --\n-- Metric 4: Failed deployment recovery time\n_incidents_for_deployments as (\n SELECT\n i.id as incident_id,\n i.created_date as incident_create_date,\n i.resolution_date as incident_resolution_date,\n fd.deployment_id as caused_by_deployment,\n fd.deployment_finished_date,\n date_format(fd.deployment_finished_date,'%y/%m') as deployment_finished_month\n FROM\n issues i\n left join project_issue_metrics pim on i.id = pim.id\n join _deployments fd on pim.deployment_id = fd.deployment_id\n WHERE\n i.type = 'INCIDENT'\n and $__timeFilter(i.resolution_date)\n),\n\n_recovery_time_ranks as (\n SELECT *, percent_rank() over(order by TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as ranks\n FROM _incidents_for_deployments\n),\n\n_median_recovery_time as (\n SELECT max(TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as median_recovery_time\n FROM _recovery_time_ranks\n WHERE ranks <= 0.5\n),\n\n_metric_recovery_time_2023_report as(\n\tSELECT \n\t\"Failed deployment recovery time\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2023' THEN\n\t\tCASE\n\t\t\tWHEN median_recovery_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\tWHEN median_recovery_time < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\tWHEN median_recovery_time < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\tWHEN median_recovery_time >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\tEND\n\tEND AS median_recovery_time\n\tFROM \n\t_median_recovery_time\n),\n\n-- ***** 2021 report ***** --\n-- Metric 4: Median time to restore service \n_incidents as (\n-- get the incidents created within the selected time period in the top-right corner\n\tSELECT\n\t distinct i.id,\n\t\tcast(lead_time_minutes as signed) as lead_time_minutes\n\tFROM\n\t\tissues i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n\t join project_mapping pm on b.id = pm.row_id and pm.`table` = 'boards'\n\tWHERE\n\t pm.project_name in (${project})\n\t\tand i.type = 'INCIDENT'\n\t\tand $__timeFilter(i.created_date)\n),\n\n_median_mttr_ranks as(\n\tSELECT *, percent_rank() over(order by lead_time_minutes) as ranks\n\tFROM _incidents\n),\n\n_median_mttr as(\n\tSELECT max(lead_time_minutes) as median_time_to_resolve\n\tFROM _median_mttr_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_mttr_2021_report as(\n\tSELECT \n\t\"Time to restore service\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE\n\t\t\t\tWHEN median_time_to_resolve < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\tWHEN median_time_to_resolve < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\t\tWHEN median_time_to_resolve < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\t\tWHEN median_time_to_resolve >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\t\tEND\n\tEND AS median_time_to_resolve\n\tFROM \n\t\t_median_mttr\n),\n\n_metric_mrt_or_mm as(\n\tSELECT \n\tmetric,\n\tmedian_recovery_time AS value\n\tFROM \n\t_metric_recovery_time_2023_report\n\tWHERE \n\t('$dora_report') = '2023'\n\tUNION\n\tSELECT \n\tmetric,\n\tmedian_time_to_resolve AS value\n\tFROM \n\t_metric_mttr_2021_report\n\tWHERE \n\t('$dora_report') = '2021'\n),\n\n_final_results as (\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m1.metric as _metric, m1.value FROM dora_benchmarks db\n\tleft join _metric_deployment_frequency m1 on db.metric = m1.metric\n\tWHERE m1.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m2.metric as _metric, m2.value FROM dora_benchmarks db\n\tleft join _metric_change_lead_time m2 on db.metric = m2.metric\n\tWHERE m2.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m3.metric as _metric, m3.value FROM dora_benchmarks db\n\tleft join _metric_cfr m3 on db.metric = m3.metric\n\tWHERE m3.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m4.metric as _metric, m4.value FROM dora_benchmarks db\n\tleft join _metric_mrt_or_mm m4 on db.metric = m4.metric\n\tWHERE m4.metric is not null and db.dora_report = ('$dora_report')\n)\n\n\nSELECT \n\tmetric,\n\tcase when low = value then low else null end as low,\n\tcase when medium = value then medium else null end as medium,\n\tcase when high = value then high else null end as high,\n\tcase when elite = value then elite else null end as elite\nFROM _final_results\nORDER BY id", "refId": "A", "select": [ [ @@ -355,7 +355,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n)\n\nSELECT \n CASE\n WHEN ('$dora_report') = '2023' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t \tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\tELSE 'Invalid dora report'\n\tEND AS 'Deployment Frequency'\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n)\n\nSELECT \n CASE\n WHEN ('$dora_report') = '2023' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t \tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\tELSE 'Invalid dora report'\n\tEND AS 'Deployment Frequency'\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n", "refId": "A", "select": [ [ diff --git a/grafana/dashboards/DORAByTeam.json b/grafana/dashboards/DORAByTeam.json index 72ced065d36..2757649d1ed 100644 --- a/grafana/dashboards/DORAByTeam.json +++ b/grafana/dashboards/DORAByTeam.json @@ -208,7 +208,7 @@ "format": "table", "hide": false, "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\t\n JOIN commits c on cdc.commit_sha = c.sha\n\tjoin user_accounts ua on c.author_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tt.name in (${team})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n),\n\n_metric_deployment_frequency as (\n\tSELECT \n\t 'Deployment frequency' as metric, \n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per day and once per week(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per week and once per month(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN 'Fewer than once per month(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per day and once per month(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN 'Between once per month and once every 6 months(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN 'Fewer than once per six months(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n),\n\n-- Metric 2: median lead time for changes\n_pr_stats as (\n-- get the cycle time of PRs deployed by the deployments finished in the selected period\n\tSELECT\n\t\tdistinct pr.id,\n\t\tppm.pr_cycle_time\n\tFROM\n\t\tpull_requests pr \n\t\tjoin user_accounts ua on pr.author_id = ua.account_id\n \tjoin users u on ua.user_id = u.id\n \tjoin team_users tu on u.id = tu.user_id\n \tjoin teams t on tu.team_id = t.id\n\t\tjoin project_pr_metrics ppm on ppm.id = pr.id\n\t\tjoin project_mapping pm on pr.base_repo_id = pm.row_id and pm.`table` = 'repos'\n\t\tjoin cicd_deployment_commits cdc on ppm.deployment_commit_id = cdc.id\n\tWHERE\n\t t.name in (${team}) \n\t\tand pr.merged_date is not null\n\t\tand ppm.pr_cycle_time is not null\n\t\tand $__timeFilter(cdc.finished_date)\n),\n\n_median_change_lead_time_ranks as(\n\tSELECT *, percent_rank() over(order by pr_cycle_time) as ranks\n\tFROM _pr_stats\n),\n\n_median_change_lead_time as(\n-- use median PR cycle time as the median change lead time\n\tSELECT max(pr_cycle_time) as median_change_lead_time\n\tFROM _median_change_lead_time_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_change_lead_time as (\n\tSELECT \n\t\t'Lead time for changes' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 24 * 60 THEN \"Less than one day(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Between one day and one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 30 * 24 * 60 THEN \"Between one week and one month(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 30 * 24 * 60 THEN \"More than one month(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Less than one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 180 * 24 * 60 THEN \"Between one week and six months(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 180 * 24 * 60 THEN \"More than six months(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\nFROM _median_change_lead_time\n),\n\n-- Metric 3: change failure rate\n_deployments as (\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(cdc.finished_date) as deployment_finished_date\n\tFROM \n\t\tcicd_deployment_commits cdc\n\t JOIN commits c on cdc.commit_sha = c.sha\n\t join user_accounts ua on c.author_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\t\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tt.name in (${team})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n\tHAVING $__timeFilter(max(cdc.finished_date))\n),\n\n_failure_caused_by_deployments as (\n-- calculate the number of incidents caused by each deployment\n\tSELECT\n\t\td.deployment_id,\n\t\td.deployment_finished_date,\n\t\tcount(distinct case when i.type = 'INCIDENT' then d.deployment_id else null end) as has_incident\n\tFROM\n\t\t_deployments d\n\t\tleft join project_issue_metrics pim on d.deployment_id = pim.deployment_id\n\t\tleft join issues i on pim.id = i.id\n\tGROUP BY 1,2\n),\n\n_change_failure_rate as (\n\tSELECT \n\t\tcase \n\t\t\twhen count(deployment_id) is null then null\n\t\t\telse sum(has_incident)/count(deployment_id) end as change_failure_rate\n\tFROM\n\t\t_failure_caused_by_deployments\n),\n\n_is_collected_data as(\n\tSELECT\n CASE \n WHEN COUNT(i.id) = 0 AND COUNT(cdc.id) = 0 THEN 'No All'\n WHEN COUNT(i.id) = 0 THEN 'No Incidents' \n WHEN COUNT(cdc.id) = 0 THEN 'No Deployments'\n END AS is_collected\nFROM\n (SELECT 1) AS dummy\nLEFT JOIN\n issues i ON i.type = 'INCIDENT'\nLEFT JOIN\n cicd_deployment_commits cdc ON 1=1\n),\n\n_metric_cfr as (\n\tSELECT\n\t\t'Change failure rate' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t WHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .05 THEN \"0-5%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .10 THEN \"5%-10%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"10%-15%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .15 THEN \"> 15%(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"0-15%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .20 THEN \"16%-20%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .30 THEN \"21%-30%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .30 THEN \"> 30%(low)\" \n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM \n\t\t_change_failure_rate, _is_collected_data\n),\n\n-- ***** 2023 report ***** --\n-- Metric 4: Failed deployment recovery time\n_incidents_for_deployments as (\n SELECT\n i.id as incident_id,\n i.created_date as incident_create_date,\n i.resolution_date as incident_resolution_date,\n fd.deployment_id as caused_by_deployment,\n fd.deployment_finished_date,\n date_format(fd.deployment_finished_date,'%y/%m') as deployment_finished_month\n FROM\n issues i\n left join project_issue_metrics pim on i.id = pim.id\n join _deployments fd on pim.deployment_id = fd.deployment_id\n WHERE\n i.type = 'INCIDENT'\n and $__timeFilter(i.resolution_date)\n),\n\n_recovery_time_ranks as (\n SELECT *, percent_rank() over(order by TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as ranks\n FROM _incidents_for_deployments\n),\n\n_median_recovery_time as (\n SELECT max(TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as median_recovery_time\n FROM _recovery_time_ranks\n WHERE ranks <= 0.5\n),\n\n_metric_recovery_time_2023_report as(\n\tSELECT \n\t\"Failed deployment recovery time\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2023' THEN\n\t\tCASE\n\t\t\tWHEN median_recovery_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\tWHEN median_recovery_time < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\tWHEN median_recovery_time < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\tWHEN median_recovery_time >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\tEND\n\tEND AS median_recovery_time\n\tFROM \n\t_median_recovery_time\n),\n\n-- ***** 2021 report ***** --\n-- Metric 4: Median time to restore service \n_incidents as (\n-- get the incidents created within the selected time period in the top-right corner\n\tSELECT\n\t distinct i.id,\n\t\tcast(lead_time_minutes as signed) as lead_time_minutes\n\tFROM\n\t\tissues i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n\t join project_mapping pm on b.id = pm.row_id and pm.`table` = 'boards'\n\t join user_accounts ua on i.assignee_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\tWHERE\n\t t.name in (${team})\n\t\tand i.type = 'INCIDENT'\n\t\tand $__timeFilter(i.created_date)\n),\n\n_median_mttr_ranks as(\n\tSELECT *, percent_rank() over(order by lead_time_minutes) as ranks\n\tFROM _incidents\n),\n\n_median_mttr as(\n\tSELECT max(lead_time_minutes) as median_time_to_resolve\n\tFROM _median_mttr_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_mttr_2021_report as(\n\tSELECT \n\t\"Time to restore service\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE\n\t\t\t\tWHEN median_time_to_resolve < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\tWHEN median_time_to_resolve < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\t\tWHEN median_time_to_resolve < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\t\tWHEN median_time_to_resolve >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\t\tEND\n\tEND AS median_time_to_resolve\n\tFROM \n\t\t_median_mttr\n),\n\n_metric_mrt_or_mm as(\n\tSELECT \n\tmetric,\n\tmedian_recovery_time AS value\n\tFROM \n\t_metric_recovery_time_2023_report\n\tWHERE \n\t('$dora_report') = '2023'\n\tUNION\n\tSELECT \n\tmetric,\n\tmedian_time_to_resolve AS value\n\tFROM \n\t_metric_mttr_2021_report\n\tWHERE \n\t('$dora_report') = '2021'\n),\n\n_final_results as (\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m1.metric as _metric, m1.value FROM dora_benchmarks db\n\tleft join _metric_deployment_frequency m1 on db.metric = m1.metric\n\tWHERE m1.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m2.metric as _metric, m2.value FROM dora_benchmarks db\n\tleft join _metric_change_lead_time m2 on db.metric = m2.metric\n\tWHERE m2.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m3.metric as _metric, m3.value FROM dora_benchmarks db\n\tleft join _metric_cfr m3 on db.metric = m3.metric\n\tWHERE m3.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m4.metric as _metric, m4.value FROM dora_benchmarks db\n\tleft join _metric_mrt_or_mm m4 on db.metric = m4.metric\n\tWHERE m4.metric is not null and db.dora_report = ('$dora_report')\n)\n\n\nSELECT \n\tmetric,\n\tcase when low = value then low else null end as low,\n\tcase when medium = value then medium else null end as medium,\n\tcase when high = value then high else null end as high,\n\tcase when elite = value then elite else null end as elite\nFROM _final_results\nORDER BY id", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\t\n JOIN commits c on cdc.commit_sha = c.sha\n\tjoin user_accounts ua on c.author_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tt.name in (${team})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n),\n\n_metric_deployment_frequency as (\n\tSELECT \n\t 'Deployment frequency' as metric, \n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per day and once per week(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per week and once per month(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN 'Fewer than once per month(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per day and once per month(high)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN 'Between once per month and once every 6 months(medium)'\n\t\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN 'Fewer than once per six months(low)'\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n),\n\n-- Metric 2: median lead time for changes\n_pr_stats as (\n-- get the cycle time of PRs deployed by the deployments finished in the selected period\n\tSELECT\n\t\tdistinct pr.id,\n\t\tppm.pr_cycle_time\n\tFROM\n\t\tpull_requests pr \n\t\tjoin user_accounts ua on pr.author_id = ua.account_id\n \tjoin users u on ua.user_id = u.id\n \tjoin team_users tu on u.id = tu.user_id\n \tjoin teams t on tu.team_id = t.id\n\t\tjoin project_pr_metrics ppm on ppm.id = pr.id\n\t\tjoin project_mapping pm on pr.base_repo_id = pm.row_id and pm.`table` = 'repos'\n\t\tjoin cicd_deployment_commits cdc on ppm.deployment_commit_id = cdc.id\n\tWHERE\n\t t.name in (${team}) \n\t\tand pr.merged_date is not null\n\t\tand ppm.pr_cycle_time is not null\n\t\tand $__timeFilter(cdc.finished_date)\n),\n\n_median_change_lead_time_ranks as(\n\tSELECT *, percent_rank() over(order by pr_cycle_time) as ranks\n\tFROM _pr_stats\n),\n\n_median_change_lead_time as(\n-- use median PR cycle time as the median change lead time\n\tSELECT max(pr_cycle_time) as median_change_lead_time\n\tFROM _median_change_lead_time_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_change_lead_time as (\n\tSELECT \n\t\t'Lead time for changes' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 24 * 60 THEN \"Less than one day(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Between one day and one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 30 * 24 * 60 THEN \"Between one week and one month(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 30 * 24 * 60 THEN \"More than one month(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE\n\t\t\t\t\tWHEN median_change_lead_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\t\tWHEN median_change_lead_time < 7 * 24 * 60 THEN \"Less than one week(high)\"\n\t\t\t\t\tWHEN median_change_lead_time < 180 * 24 * 60 THEN \"Between one week and six months(medium)\"\n\t\t\t\t\tWHEN median_change_lead_time >= 180 * 24 * 60 THEN \"More than six months(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/pull_requests.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\nFROM _median_change_lead_time\n),\n\n-- Metric 3: change failure rate\n_deployments as (\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(cdc.finished_date) as deployment_finished_date\n\tFROM \n\t\tcicd_deployment_commits cdc\n\t JOIN commits c on cdc.commit_sha = c.sha\n\t join user_accounts ua on c.author_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\t\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tt.name in (${team})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n\tHAVING $__timeFilter(max(cdc.finished_date))\n),\n\n_failure_caused_by_deployments as (\n-- calculate the number of incidents caused by each deployment\n\tSELECT\n\t\td.deployment_id,\n\t\td.deployment_finished_date,\n\t\tcount(distinct case when i.type = 'INCIDENT' then d.deployment_id else null end) as has_incident\n\tFROM\n\t\t_deployments d\n\t\tleft join project_issue_metrics pim on d.deployment_id = pim.deployment_id\n\t\tleft join issues i on pim.id = i.id\n\tGROUP BY 1,2\n),\n\n_change_failure_rate as (\n\tSELECT \n\t\tcase \n\t\t\twhen count(deployment_id) is null then null\n\t\t\telse sum(has_incident)/count(deployment_id) end as change_failure_rate\n\tFROM\n\t\t_failure_caused_by_deployments\n),\n\n_is_collected_data as(\n\tSELECT\n CASE \n WHEN COUNT(i.id) = 0 AND COUNT(cdc.id) = 0 THEN 'No All'\n WHEN COUNT(i.id) = 0 THEN 'No Incidents' \n WHEN COUNT(cdc.id) = 0 THEN 'No Deployments'\n END AS is_collected\nFROM\n (SELECT 1) AS dummy\nLEFT JOIN\n issues i ON i.type = 'INCIDENT'\nLEFT JOIN\n cicd_deployment_commits cdc ON 1=1\n),\n\n_metric_cfr as (\n\tSELECT\n\t\t'Change failure rate' as metric,\n\t\tCASE\n\t\t\tWHEN ('$dora_report') = '2023' THEN\n\t\t\t\tCASE \n\t\t\t\t WHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .05 THEN \"0-5%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .10 THEN \"5%-10%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"10%-15%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .15 THEN \"> 15%(low)\"\n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\t\tCASE \n\t\t\t\t\tWHEN is_collected = \"No All\" THEN \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t WHEN is_collected = \"No Incidents\" THEN \"N/A. Please check if you have collected incidents.\"\n\t\t\t\t WHEN is_collected = \"No Deployments\" THEN \"N/A. Please check if you have collected deployments.\"\n\t\t\t\t\tWHEN change_failure_rate <= .15 THEN \"0-15%(elite)\"\n\t\t\t\t\tWHEN change_failure_rate <= .20 THEN \"16%-20%(high)\"\n\t\t\t\t\tWHEN change_failure_rate <= .30 THEN \"21%-30%(medium)\"\n\t\t\t\t\tWHEN change_failure_rate > .30 THEN \"> 30%(low)\" \n\t\t\t\t\tELSE \"N/A. Please check if you have collected deployments/incidents.\"\n\t\t\t\t\tEND\n\t\t\tELSE 'Invalid dora report'\n\t\tEND AS value\n\tFROM \n\t\t_change_failure_rate, _is_collected_data\n),\n\n-- ***** 2023 report ***** --\n-- Metric 4: Failed deployment recovery time\n_incidents_for_deployments as (\n SELECT\n i.id as incident_id,\n i.created_date as incident_create_date,\n i.resolution_date as incident_resolution_date,\n fd.deployment_id as caused_by_deployment,\n fd.deployment_finished_date,\n date_format(fd.deployment_finished_date,'%y/%m') as deployment_finished_month\n FROM\n issues i\n left join project_issue_metrics pim on i.id = pim.id\n join _deployments fd on pim.deployment_id = fd.deployment_id\n WHERE\n i.type = 'INCIDENT'\n and $__timeFilter(i.resolution_date)\n),\n\n_recovery_time_ranks as (\n SELECT *, percent_rank() over(order by TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as ranks\n FROM _incidents_for_deployments\n),\n\n_median_recovery_time as (\n SELECT max(TIMESTAMPDIFF(MINUTE, deployment_finished_date, incident_resolution_date)) as median_recovery_time\n FROM _recovery_time_ranks\n WHERE ranks <= 0.5\n),\n\n_metric_recovery_time_2023_report as(\n\tSELECT \n\t\"Failed deployment recovery time\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2023' THEN\n\t\tCASE\n\t\t\tWHEN median_recovery_time < 60 THEN \"Less than one hour(elite)\"\n\t\t\tWHEN median_recovery_time < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\tWHEN median_recovery_time < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\tWHEN median_recovery_time >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\tEND\n\tEND AS median_recovery_time\n\tFROM \n\t_median_recovery_time\n),\n\n-- ***** 2021 report ***** --\n-- Metric 4: Median time to restore service \n_incidents as (\n-- get the incidents created within the selected time period in the top-right corner\n\tSELECT\n\t distinct i.id,\n\t\tcast(lead_time_minutes as signed) as lead_time_minutes\n\tFROM\n\t\tissues i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n\t join project_mapping pm on b.id = pm.row_id and pm.`table` = 'boards'\n\t join user_accounts ua on i.assignee_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\tWHERE\n\t t.name in (${team})\n\t\tand i.type = 'INCIDENT'\n\t\tand $__timeFilter(i.created_date)\n),\n\n_median_mttr_ranks as(\n\tSELECT *, percent_rank() over(order by lead_time_minutes) as ranks\n\tFROM _incidents\n),\n\n_median_mttr as(\n\tSELECT max(lead_time_minutes) as median_time_to_resolve\n\tFROM _median_mttr_ranks\n\tWHERE ranks <= 0.5\n),\n\n_metric_mttr_2021_report as(\n\tSELECT \n\t\"Time to restore service\" as metric,\n\tCASE\n\t\tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE\n\t\t\t\tWHEN median_time_to_resolve < 60 THEN \"Less than one hour(elite)\"\n\t\t\t\tWHEN median_time_to_resolve < 24 * 60 THEN \"Less than one day(high)\"\n\t\t\t\tWHEN median_time_to_resolve < 7 * 24 * 60 THEN \"Between one day and one week(medium)\"\n\t\t\t\tWHEN median_time_to_resolve >= 7 * 24 * 60 THEN \"More than one week(low)\"\n\t\t\t\tELSE \"N/A. Please check if you have collected incidents.\"\n\t\t\tEND\n\tEND AS median_time_to_resolve\n\tFROM \n\t\t_median_mttr\n),\n\n_metric_mrt_or_mm as(\n\tSELECT \n\tmetric,\n\tmedian_recovery_time AS value\n\tFROM \n\t_metric_recovery_time_2023_report\n\tWHERE \n\t('$dora_report') = '2023'\n\tUNION\n\tSELECT \n\tmetric,\n\tmedian_time_to_resolve AS value\n\tFROM \n\t_metric_mttr_2021_report\n\tWHERE \n\t('$dora_report') = '2021'\n),\n\n_final_results as (\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m1.metric as _metric, m1.value FROM dora_benchmarks db\n\tleft join _metric_deployment_frequency m1 on db.metric = m1.metric\n\tWHERE m1.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m2.metric as _metric, m2.value FROM dora_benchmarks db\n\tleft join _metric_change_lead_time m2 on db.metric = m2.metric\n\tWHERE m2.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m3.metric as _metric, m3.value FROM dora_benchmarks db\n\tleft join _metric_cfr m3 on db.metric = m3.metric\n\tWHERE m3.metric is not null and db.dora_report = ('$dora_report')\n\t\n\tunion \n\t\n\tSELECT distinct db.id,db.metric,db.low,db.medium,db.high,db.elite,m4.metric as _metric, m4.value FROM dora_benchmarks db\n\tleft join _metric_mrt_or_mm m4 on db.metric = m4.metric\n\tWHERE m4.metric is not null and db.dora_report = ('$dora_report')\n)\n\n\nSELECT \n\tmetric,\n\tcase when low = value then low else null end as low,\n\tcase when medium = value then medium else null end as medium,\n\tcase when high = value then high else null end as high,\n\tcase when elite = value then elite else null end as elite\nFROM _final_results\nORDER BY id", "refId": "A", "sql": { "columns": [ @@ -326,7 +326,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN commits c on cdc.commit_sha = c.sha\n\tjoin user_accounts ua on c.author_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tt.name in (${team})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n)\n\nSELECT \n CASE\n WHEN ('$dora_report') = '2023' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t \tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\tELSE 'Invalid dora report'\n\tEND AS 'Deployment Frequency'\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n\n", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN commits c on cdc.commit_sha = c.sha\n\tjoin user_accounts ua on c.author_id = ua.account_id\n join users u on ua.user_id = u.id\n join team_users tu on u.id = tu.user_id\n join teams t on tu.team_id = t.id\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tt.name in (${team})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, 0)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n)\n\nSELECT \n CASE\n WHEN ('$dora_report') = '2023' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t \tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN CONCAT(median_number_of_deployment_days_per_week, ' deployment days per week(elite)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN CONCAT(median_number_of_deployment_days_per_month, ' deployment days per month(high)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(medium)')\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN CONCAT(median_number_of_deployment_days_per_six_months, ' deployment days per six months(low)')\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\tELSE 'Invalid dora report'\n\tEND AS 'Deployment Frequency'\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n\n", "refId": "A", "select": [ [ diff --git a/grafana/dashboards/DORADebug.json b/grafana/dashboards/DORADebug.json index ca6bc623632..ddc6f4caf86 100644 --- a/grafana/dashboards/DORADebug.json +++ b/grafana/dashboards/DORADebug.json @@ -321,7 +321,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n)\n\nSELECT \n CASE\n WHEN ('$dora_report') = '2023' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per day and once per week(high)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per week and once per month(medium)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN 'Fewer than once per month(low)'\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t \tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per day and once per month(high)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN 'Between once per month and once every 6 months(medium)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN 'Fewer than once per six months(low)'\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\tELSE 'Invalid dora report'\n\tEND AS 'Deployment Frequency'\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n)\n\nSELECT \n CASE\n WHEN ('$dora_report') = '2023' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 1 THEN 'Between once per day and once per week(high)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per week and once per month(medium)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_month < 1 and is_collected is not null THEN 'Fewer than once per month(low)'\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t \tWHEN ('$dora_report') = '2021' THEN\n\t\t\tCASE \n\t\t\t\tWHEN median_number_of_deployment_days_per_week >= 7 THEN 'On-demand(elite)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_month >= 1 THEN 'Between once per day and once per month(high)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months >= 1 THEN 'Between once per month and once every 6 months(medium)'\n\t\t\t\tWHEN median_number_of_deployment_days_per_six_months < 1 and is_collected is not null THEN 'Fewer than once per six months(low)'\n\t\t\t\tELSE \"N/A. Please check if you have collected deployments.\" END\n\t\tELSE 'Invalid dora report'\n\tEND AS 'Deployment Frequency'\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months\n", "refId": "A", "select": [ [ diff --git a/grafana/dashboards/DORADrillDown.json b/grafana/dashboards/DORADrillDown.json index c77af9c4a5a..23cca877afe 100644 --- a/grafana/dashboards/DORADrillDown.json +++ b/grafana/dashboards/DORADrillDown.json @@ -437,7 +437,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > FROM_UNIXTIME(1692502887)\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in ('p1')\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(day), INTERVAL -WEEKDAY(date(day)) DAY)) as start_of_week\n FROM last_few_calendar_months\n ORDER BY 1 asc\n)\n\n\nSELECT \n concat(date_format(cw.start_of_week,'%m/%d'), ' - ', date_format(DATE_ADD(cw.start_of_week, INTERVAL +6 DAY),'%m/%d')) as week,\n days_deployed\nfrom calendar_weeks cw left join _days_weekly_deploy b on cw.start_of_week = b.week", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > FROM_UNIXTIME(1692502887)\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in ('p1')\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(day), INTERVAL -WEEKDAY(date(day)) DAY)) as start_of_week\n FROM last_few_calendar_months\n ORDER BY 1 asc\n)\n\n\nSELECT \n concat(date_format(cw.start_of_week,'%m/%d'), ' - ', date_format(DATE_ADD(cw.start_of_week, INTERVAL +6 DAY),'%m/%d')) as week,\n days_deployed\nfrom calendar_weeks cw left join _days_weekly_deploy b on cw.start_of_week = b.week", "refId": "A", "select": [ [ @@ -566,7 +566,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > FROM_UNIXTIME(1692502887)\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in ('p1')\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n)\n\n\n\nSELECT \n DATE_FORMAT(month, '%y/%m') as month, days_deployed\nFROM _days_monthly_deploy", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > FROM_UNIXTIME(1692502887)\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in ('p1')\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n)\n\n\n\nSELECT \n DATE_FORMAT(month, '%y/%m') as month, days_deployed\nFROM _days_monthly_deploy", "refId": "A", "select": [ [ @@ -694,7 +694,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > FROM_UNIXTIME(1692502887)\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in ('p1')\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n)\n\n\n\nSELECT \n CONCAT(DATE_FORMAT(DATE_SUB(month, INTERVAL 5 MONTH), '%y/%m'), ' ~ ', DATE_FORMAT(month, '%y/%m')) AS month_range, days_deployed_per_six_months as days_deployed\nFROM _days_six_months_deploy\nORDER BY month", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > FROM_UNIXTIME(1692502887)\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in ('p1')\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n)\n\n\n\nSELECT \n CONCAT(DATE_FORMAT(DATE_SUB(month, INTERVAL 5 MONTH), '%y/%m'), ' ~ ', DATE_FORMAT(month, '%y/%m')) AS month_range, days_deployed_per_six_months as days_deployed\nFROM _days_six_months_deploy\nORDER BY month", "refId": "A", "select": [ [ @@ -830,7 +830,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n),\n\n_tolal_production_deployment_days as(\n\tselect \n\tcount(*) as tpdd,\n\tcount(distinct day) as dtpdd\n\tfrom _production_deployment_days\n)\n\nSELECT \n -- tpdd as \"Production Deploy Counts\",\n\tdtpdd as \"Production Deployment Days\",\n median_number_of_deployment_days_per_week as \"Median weekly deployment days\",\n\tmedian_number_of_deployment_days_per_month as \"Median monthly deployment days\",\n\tmedian_number_of_deployment_days_per_six_months as \"Median semi-annual deployment days\"\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months, _tolal_production_deployment_days", + "rawSql": "-- Metric 1: Deployment Frequency\nwith last_few_calendar_months as(\n-- construct the last few calendar months within the selected time period in the top-right corner\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) day\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) > $__timeFrom()\n),\n\n_production_deployment_days as(\n-- When deploying multiple commits in one pipeline, GitLab and BitBucket may generate more than one deployment. However, DevLake consider these deployments as ONE production deployment and use the last one's finished_date as the finished date.\n\tSELECT\n\t\tcdc.cicd_deployment_id as deployment_id,\n\t\tmax(DATE(cdc.finished_date)) as day\n\tFROM cicd_deployment_commits cdc\n\tJOIN project_mapping pm on cdc.cicd_scope_id = pm.row_id and pm.`table` = 'cicd_scopes'\n\tWHERE\n\t\tpm.project_name in (${project})\n\t\tand cdc.result = 'SUCCESS'\n\t\tand cdc.environment = 'PRODUCTION'\n\tGROUP BY 1\n),\n\n_days_weekly_deploy as(\n-- calculate the number of deployment days every week\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -WEEKDAY(last_few_calendar_months.day) DAY)) as week,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as weeks_deployed,\n\t\t\tCOUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY week\n\t),\n\n_days_monthly_deploy as(\n-- calculate the number of deployment days every month\n\tSELECT\n\t\t\tdate(DATE_ADD(last_few_calendar_months.day, INTERVAL -DAY(last_few_calendar_months.day)+1 DAY)) as month,\n\t\t\tMAX(if(_production_deployment_days.day is not null, 1, null)) as months_deployed,\n\t\t COUNT(distinct _production_deployment_days.day) as days_deployed\n\tFROM \n\t\tlast_few_calendar_months\n\t\tLEFT JOIN _production_deployment_days ON _production_deployment_days.day = last_few_calendar_months.day\n\tGROUP BY month\n\t),\n\n_days_six_months_deploy AS (\n SELECT\n month,\n SUM(days_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS days_deployed_per_six_months,\n COUNT(months_deployed) OVER (\n ORDER BY month\n ROWS BETWEEN 5 PRECEDING AND CURRENT ROW\n ) AS months_deployed_count,\n ROW_NUMBER() OVER (\n PARTITION BY DATE_FORMAT(month, '%Y-%m') DIV 6\n ORDER BY month DESC\n ) AS rn\n FROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_week_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_weekly_deploy\n),\n\n_median_number_of_deployment_days_per_week as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_week\n\tFROM _median_number_of_deployment_days_per_week_ranks\n\tWHERE ranks <= 0.5\n),\n\n_median_number_of_deployment_days_per_month_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed) as ranks\n\tFROM _days_monthly_deploy\n),\n\n_median_number_of_deployment_days_per_month as(\n\tSELECT max(days_deployed) as median_number_of_deployment_days_per_month\n\tFROM _median_number_of_deployment_days_per_month_ranks\n\tWHERE ranks <= 0.5\n),\n\n_days_per_six_months_deploy_by_filter AS (\nSELECT\n month,\n days_deployed_per_six_months,\n months_deployed_count\nFROM _days_six_months_deploy\nWHERE rn%6 = 1\n),\n\n\n_median_number_of_deployment_days_per_six_months_ranks as(\n\tSELECT *, percent_rank() over(order by days_deployed_per_six_months) as ranks\n\tFROM _days_per_six_months_deploy_by_filter\n),\n\n_median_number_of_deployment_days_per_six_months as(\n\tSELECT min(days_deployed_per_six_months) as median_number_of_deployment_days_per_six_months, min(months_deployed_count) as is_collected\n\tFROM _median_number_of_deployment_days_per_six_months_ranks\n\tWHERE ranks >= 0.5\n),\n\n_tolal_production_deployment_days as(\n\tselect \n\tcount(*) as tpdd,\n\tcount(distinct day) as dtpdd\n\tfrom _production_deployment_days\n)\n\nSELECT \n -- tpdd as \"Production Deploy Counts\",\n\tdtpdd as \"Production Deployment Days\",\n median_number_of_deployment_days_per_week as \"Median weekly deployment days\",\n\tmedian_number_of_deployment_days_per_month as \"Median monthly deployment days\",\n\tmedian_number_of_deployment_days_per_six_months as \"Median semi-annual deployment days\"\nFROM _median_number_of_deployment_days_per_week, _median_number_of_deployment_days_per_month, _median_number_of_deployment_days_per_six_months, _tolal_production_deployment_days", "refId": "A", "select": [ [ diff --git a/grafana/dashboards/WeeklyBugRetro.json b/grafana/dashboards/WeeklyBugRetro.json index df90e103a38..9a6d8ff5b83 100644 --- a/grafana/dashboards/WeeklyBugRetro.json +++ b/grafana/dashboards/WeeklyBugRetro.json @@ -1631,7 +1631,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "with bugs as ( \n select \n DATE_ADD(date(i.created_date), INTERVAL -WEEKDAY(date(i.created_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and $__timeFilter(i.created_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\ncalendar_date as(\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) d\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) >= (SYSDATE()-INTERVAL 6 MONTH)\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(d), INTERVAL -WEEKDAY(date(d)) DAY)) as start_of_week\n FROM calendar_date\n ORDER BY 1 asc\n)\n\n\nselect \n concat(date_format(cw.start_of_week,'%m/%d'), ' - ', date_format(DATE_ADD(cw.start_of_week, INTERVAL +6 DAY),'%m/%d')) as week,\n case when bug_count is not null then bug_count else 0 end as 'Weekly New Bugs'\nfrom calendar_weeks cw left join bugs b on cw.start_of_week = b.time\norder by cw.start_of_week asc\n", + "rawSql": "with bugs as ( \n select \n DATE_ADD(date(i.created_date), INTERVAL -WEEKDAY(date(i.created_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and $__timeFilter(i.created_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\ncalendar_date as(\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) d\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) >= ($__timeTo()-INTERVAL 6 MONTH)\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(d), INTERVAL -WEEKDAY(date(d)) DAY)) as start_of_week\n FROM calendar_date\n ORDER BY 1 asc\n)\n\n\nselect \n concat(date_format(cw.start_of_week,'%m/%d'), ' - ', date_format(DATE_ADD(cw.start_of_week, INTERVAL +6 DAY),'%m/%d')) as week,\n case when bug_count is not null then bug_count else 0 end as 'Weekly New Bugs'\nfrom calendar_weeks cw left join bugs b on cw.start_of_week = b.time\norder by cw.start_of_week asc\n", "refId": "A", "select": [ [ @@ -1766,7 +1766,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "with bugs as (\n select \n DATE_ADD(date(i.resolution_date), INTERVAL -WEEKDAY(date(i.resolution_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and status = 'DONE'\n and $__timeFilter(i.resolution_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\ncalendar_date as(\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) d\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) >= (SYSDATE()-INTERVAL 6 MONTH)\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(d), INTERVAL -WEEKDAY(date(d)) DAY)) as start_of_week\n FROM calendar_date\n ORDER BY 1 asc\n)\n\nselect \n concat(date_format(cw.start_of_week,'%m/%d'), ' - ', date_format(DATE_ADD(cw.start_of_week, INTERVAL +6 DAY),'%m/%d')) as week,\n case when bug_count is not null then bug_count else 0 end as 'Weekly Closed Bugs'\nfrom calendar_weeks cw left join bugs b on cw.start_of_week = b.time\norder by cw.start_of_week asc", + "rawSql": "with bugs as (\n select \n DATE_ADD(date(i.resolution_date), INTERVAL -WEEKDAY(date(i.resolution_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and status = 'DONE'\n and $__timeFilter(i.resolution_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\ncalendar_date as(\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) d\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) >= ($__timeTo()-INTERVAL 6 MONTH)\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(d), INTERVAL -WEEKDAY(date(d)) DAY)) as start_of_week\n FROM calendar_date\n ORDER BY 1 asc\n)\n\nselect \n concat(date_format(cw.start_of_week,'%m/%d'), ' - ', date_format(DATE_ADD(cw.start_of_week, INTERVAL +6 DAY),'%m/%d')) as week,\n case when bug_count is not null then bug_count else 0 end as 'Weekly Closed Bugs'\nfrom calendar_weeks cw left join bugs b on cw.start_of_week = b.time\norder by cw.start_of_week asc", "refId": "A", "select": [ [ @@ -1903,7 +1903,7 @@ "metricColumn": "none", "queryType": "randomWalk", "rawQuery": true, - "rawSql": "with calendar_date as(\n\tSELECT CAST((SYSDATE()-INTERVAL (H+T+U) DAY) AS date) d\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t(SYSDATE()-INTERVAL (H+T+U) DAY) >= (SYSDATE()-INTERVAL 6 MONTH)\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(d), INTERVAL -WEEKDAY(date(d)) DAY)) as start_of_week\n FROM calendar_date\n ORDER BY 1 asc\n),\n\ncreated_bugs as ( \n select \n DATE_ADD(date(i.created_date), INTERVAL -WEEKDAY(date(i.created_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and $__timeFilter(i.created_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\nresolved_bugs as (\n select \n DATE_ADD(date(i.resolution_date), INTERVAL -WEEKDAY(date(i.resolution_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and status = 'DONE'\n and $__timeFilter(i.resolution_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\nweekly_new_bug as(\n select\n cw.start_of_week as week,\n case when bug_count is not null then bug_count else 0 end as weekly_new_bug\n from calendar_weeks cw left join created_bugs cb on cw.start_of_week = cb.time\n),\n\nweekly_closed_bug as(\n select\n cw.start_of_week as week,\n case when bug_count is not null then bug_count else 0 end as weekly_closed_bug\n from calendar_weeks cw left join resolved_bugs cb on cw.start_of_week = cb.time\n),\n\nweekly_updates as(\n SELECT t1.week, weekly_new_bug, weekly_closed_bug FROM weekly_new_bug t1\n LEFT JOIN weekly_closed_bug t2 ON t1.week = t2.week\n UNION\n SELECT t1.week, weekly_new_bug, weekly_closed_bug FROM weekly_new_bug t1\n RIGHT JOIN weekly_closed_bug t2 ON t1.week = t2.week\n),\n\n\noriginal_open_bugs as (\n SELECT \n count(distinct i.id) as original_open_bug_count\n FROM\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and i.created_date < $__timeFrom()\n and (i.status != 'DONE' or $__timeFilter(i.resolution_date))\n and b.id in (${board_id})\n),\n\nweekly_updated_without_null as(\n SELECT \n week, \n COALESCE(weekly_new_bug,0) as weekly_new_bug, \n COALESCE(weekly_closed_bug,0) as weekly_closed_bug,\n original_open_bug_count\n from weekly_updates, original_open_bugs\n where week is not null\n),\n\nweekly_delta as(\n SELECT \n *,\n (weekly_new_bug - weekly_closed_bug) as weekly_delta\n from weekly_updated_without_null\n order by week asc\n),\n\nfinal_data as(\n SELECT \n *,\n concat(date_format(week,'%m/%d'), ' - ', date_format(DATE_ADD(week, INTERVAL +6 DAY),'%m/%d')) as _week,\n sum(weekly_delta) over(order by week asc) as weekly_accumulated\n from weekly_delta\n)\n\nSELECT \n _week,\n (original_open_bug_count + weekly_accumulated) as \"Total No. of Outstanding Bugs By the End of Week\" from final_data", + "rawSql": "with calendar_date as(\n\tSELECT CAST(($__timeTo()-INTERVAL (H+T+U) DAY) AS date) d\n\tFROM ( SELECT 0 H\n\t\t\tUNION ALL SELECT 100 UNION ALL SELECT 200 UNION ALL SELECT 300\n\t\t) H CROSS JOIN ( SELECT 0 T\n\t\t\tUNION ALL SELECT 10 UNION ALL SELECT 20 UNION ALL SELECT 30\n\t\t\tUNION ALL SELECT 40 UNION ALL SELECT 50 UNION ALL SELECT 60\n\t\t\tUNION ALL SELECT 70 UNION ALL SELECT 80 UNION ALL SELECT 90\n\t\t) T CROSS JOIN ( SELECT 0 U\n\t\t\tUNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3\n\t\t\tUNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6\n\t\t\tUNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9\n\t\t) U\n\tWHERE\n\t\t($__timeTo()-INTERVAL (H+T+U) DAY) >= ($__timeTo()-INTERVAL 6 MONTH)\n),\n\ncalendar_weeks as(\n select \n \tdistinct date(DATE_ADD(date(d), INTERVAL -WEEKDAY(date(d)) DAY)) as start_of_week\n FROM calendar_date\n ORDER BY 1 asc\n),\n\ncreated_bugs as ( \n select \n DATE_ADD(date(i.created_date), INTERVAL -WEEKDAY(date(i.created_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and $__timeFilter(i.created_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\nresolved_bugs as (\n select \n DATE_ADD(date(i.resolution_date), INTERVAL -WEEKDAY(date(i.resolution_date)) DAY) as time,\n count(distinct i.id) as bug_count\n from\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and status = 'DONE'\n and $__timeFilter(i.resolution_date)\n and b.id in (${board_id})\n group by time\n order by time desc\n),\n\nweekly_new_bug as(\n select\n cw.start_of_week as week,\n case when bug_count is not null then bug_count else 0 end as weekly_new_bug\n from calendar_weeks cw left join created_bugs cb on cw.start_of_week = cb.time\n),\n\nweekly_closed_bug as(\n select\n cw.start_of_week as week,\n case when bug_count is not null then bug_count else 0 end as weekly_closed_bug\n from calendar_weeks cw left join resolved_bugs cb on cw.start_of_week = cb.time\n),\n\nweekly_updates as(\n SELECT t1.week, weekly_new_bug, weekly_closed_bug FROM weekly_new_bug t1\n LEFT JOIN weekly_closed_bug t2 ON t1.week = t2.week\n UNION\n SELECT t1.week, weekly_new_bug, weekly_closed_bug FROM weekly_new_bug t1\n RIGHT JOIN weekly_closed_bug t2 ON t1.week = t2.week\n),\n\n\noriginal_open_bugs as (\n SELECT \n count(distinct i.id) as original_open_bug_count\n FROM\n issues as i\n\t join board_issues bi on i.id = bi.issue_id\n\t join boards b on bi.board_id = b.id\n where \n i.type in (${issue_type})\n and i.created_date < $__timeFrom()\n and (i.status != 'DONE' or $__timeFilter(i.resolution_date))\n and b.id in (${board_id})\n),\n\nweekly_updated_without_null as(\n SELECT \n week, \n COALESCE(weekly_new_bug,0) as weekly_new_bug, \n COALESCE(weekly_closed_bug,0) as weekly_closed_bug,\n original_open_bug_count\n from weekly_updates, original_open_bugs\n where week is not null\n),\n\nweekly_delta as(\n SELECT \n *,\n (weekly_new_bug - weekly_closed_bug) as weekly_delta\n from weekly_updated_without_null\n order by week asc\n),\n\nfinal_data as(\n SELECT \n *,\n concat(date_format(week,'%m/%d'), ' - ', date_format(DATE_ADD(week, INTERVAL +6 DAY),'%m/%d')) as _week,\n sum(weekly_delta) over(order by week asc) as weekly_accumulated\n from weekly_delta\n)\n\nSELECT \n _week,\n (original_open_bug_count + weekly_accumulated) as \"Total No. of Outstanding Bugs By the End of Week\" from final_data", "refId": "A", "select": [ [