139 lines
4.8 KiB
SQL
139 lines
4.8 KiB
SQL
/*
|
|
Baseline vs rolling evaluation template
|
|
=======================================
|
|
|
|
Purpose:
|
|
Compare a fixed baseline cohort with rolling evaluation periods.
|
|
|
|
Typical use:
|
|
- A medicines optimisation search where the baseline is fixed.
|
|
- Later periods check whether the same patients still meet criteria.
|
|
- Output is practice x period, preserving the baseline count.
|
|
|
|
Replace medicine_products and the evaluation criteria before use.
|
|
*/
|
|
|
|
SET BASELINE_START = '2025-04-01';
|
|
SET BASELINE_END = '2025-06-30';
|
|
SET FIRST_EVALUATION_START = '2025-04-01';
|
|
SET EVALUATION_MONTHS = 3;
|
|
SET BNF_PREFIX = 'REPLACE_WITH_BNF_PREFIX';
|
|
|
|
WITH latest_prescribing_date AS (
|
|
-- Caps generated periods to data already present in the prescribing table.
|
|
SELECT MAX("DateMedicationStart")::DATE AS "MaxDate"
|
|
FROM REPORTING_DATASETS_ICB.SCRATCHPAD."MEDS__UnifiedPrescribingTable"
|
|
WHERE "DateMedicationStart" <= CURRENT_DATE()
|
|
),
|
|
periods AS (
|
|
-- Generates candidate month starts; increase ROWCOUNT for longer projects.
|
|
SELECT
|
|
ROW_NUMBER() OVER (ORDER BY SEQ4()) AS "PeriodNumber",
|
|
DATEADD(MONTH, ROW_NUMBER() OVER (ORDER BY SEQ4()) - 1, $FIRST_EVALUATION_START::DATE)::DATE AS "PeriodStartDate"
|
|
FROM TABLE(GENERATOR(ROWCOUNT => 48))
|
|
),
|
|
evaluation_periods AS (
|
|
SELECT
|
|
"PeriodNumber",
|
|
"PeriodStartDate",
|
|
LAST_DAY(DATEADD(MONTH, $EVALUATION_MONTHS - 1, "PeriodStartDate"))::DATE AS "PeriodEndDate"
|
|
FROM periods
|
|
CROSS JOIN latest_prescribing_date
|
|
WHERE "PeriodStartDate" <= "MaxDate"
|
|
),
|
|
date_bounds AS (
|
|
SELECT
|
|
$BASELINE_START::DATE AS "MinEventDate",
|
|
GREATEST($BASELINE_END::DATE, COALESCE(MAX("PeriodEndDate"), $BASELINE_END::DATE)) AS "MaxEventDate"
|
|
FROM evaluation_periods
|
|
),
|
|
practices AS (
|
|
-- Default to active Norfolk and Suffolk parent GP practices.
|
|
SELECT DISTINCT
|
|
"OrganisationCode" AS "PracticeCode",
|
|
"OrganisationName" AS "PracticeName"
|
|
FROM DATA_HUB.DWH."DimOrganisationAndSite"
|
|
WHERE "OrganisationSubType" = 'GP Practice'
|
|
AND "IsSiteActive" = 'Yes'
|
|
AND "IsSiteNorfolkAndSuffolk" = 'Yes'
|
|
AND "SiteCode" = "OrganisationCode"
|
|
),
|
|
medicine_products AS (
|
|
-- Replace this CTE for VTM, VMP, explicit SNOMED, or cluster-based definitions.
|
|
SELECT DISTINCT "ProductSnomedCode"
|
|
FROM DATA_HUB.DWH."DimMedicineAndDevice"
|
|
WHERE "BNFCode" LIKE $BNF_PREFIX || '%'
|
|
),
|
|
medicine_events AS (
|
|
-- Pull the smallest event window needed for both baseline and evaluation.
|
|
SELECT DISTINCT
|
|
rx."PersonKey",
|
|
rx."CurrentGeneralPractice" AS "PracticeCode",
|
|
rx."DateMedicationStart"
|
|
FROM REPORTING_DATASETS_ICB.SCRATCHPAD."MEDS__UnifiedPrescribingTable" rx
|
|
CROSS JOIN date_bounds db
|
|
INNER JOIN medicine_products mp
|
|
ON rx."SNOMEDCode" = mp."ProductSnomedCode"
|
|
WHERE rx."PersonKey" IS NOT NULL
|
|
AND rx."CurrentGeneralPractice" IS NOT NULL
|
|
AND rx."DateMedicationStart" BETWEEN db."MinEventDate" AND db."MaxEventDate"
|
|
),
|
|
baseline_cohort AS (
|
|
-- Fixes each patient to the practice recorded during the baseline window.
|
|
SELECT DISTINCT
|
|
me."PersonKey",
|
|
me."PracticeCode"
|
|
FROM medicine_events me
|
|
WHERE me."DateMedicationStart" BETWEEN $BASELINE_START AND $BASELINE_END
|
|
),
|
|
baseline_counts AS (
|
|
SELECT
|
|
"PracticeCode",
|
|
COUNT(DISTINCT "PersonKey") AS "BaselineCount"
|
|
FROM baseline_cohort
|
|
GROUP BY "PracticeCode"
|
|
),
|
|
practice_periods AS (
|
|
-- Ensures every active practice returns one row per evaluation period.
|
|
SELECT
|
|
p."PracticeCode",
|
|
p."PracticeName",
|
|
ep."PeriodNumber",
|
|
ep."PeriodStartDate",
|
|
ep."PeriodEndDate"
|
|
FROM practices p
|
|
CROSS JOIN evaluation_periods ep
|
|
),
|
|
evaluation_counts AS (
|
|
SELECT
|
|
bc."PracticeCode",
|
|
ep."PeriodNumber",
|
|
ep."PeriodStartDate",
|
|
ep."PeriodEndDate",
|
|
COUNT(DISTINCT me."PersonKey") AS "EvaluationCount"
|
|
FROM baseline_cohort bc
|
|
CROSS JOIN evaluation_periods ep
|
|
LEFT JOIN medicine_events me
|
|
ON me."PersonKey" = bc."PersonKey"
|
|
AND me."DateMedicationStart" BETWEEN ep."PeriodStartDate" AND ep."PeriodEndDate"
|
|
GROUP BY bc."PracticeCode", ep."PeriodNumber", ep."PeriodStartDate", ep."PeriodEndDate"
|
|
)
|
|
SELECT
|
|
pp."PracticeCode",
|
|
pp."PracticeName",
|
|
pp."PeriodNumber",
|
|
pp."PeriodStartDate",
|
|
pp."PeriodEndDate",
|
|
COALESCE(bc."BaselineCount", 0) AS "BaselineCount",
|
|
COALESCE(ec."EvaluationCount", 0) AS "EvaluationCount",
|
|
COALESCE(bc."BaselineCount", 0) - COALESCE(ec."EvaluationCount", 0) AS "ReductionFromBaseline"
|
|
FROM practice_periods pp
|
|
LEFT JOIN baseline_counts bc
|
|
ON pp."PracticeCode" = bc."PracticeCode"
|
|
LEFT JOIN evaluation_counts ec
|
|
ON pp."PracticeCode" = ec."PracticeCode"
|
|
AND pp."PeriodNumber" = ec."PeriodNumber"
|
|
ORDER BY
|
|
pp."PracticeName",
|
|
pp."PeriodNumber";
|