Files
medicines-snowflake/02_prescribing_analysis/prescribing_spend_by_patient_template.sql
T
Andrew Charlwood 647d1bfa7f initial commit
2026-05-12 16:40:03 +01:00

100 lines
3.4 KiB
SQL

/*
Prescribing spend by patient template
=====================================
Purpose:
Rank patients by estimated prescribing cost over a selected period and
medicine definition.
Use this when looking for high-cost patients or checking the shape of cost
concentration before doing deeper clinical review.
Default source is the maintained unified prescribing table, which already
includes parsed quantity and estimated price. If that table is unavailable
or needs rebuilding, see 06_advanced_methods/product_price_and_quantity_parsing_template.sql.
Keep at least one medicine filter set. Leaving BNF, VTM, and VMP filters all
NULL can scan all prescribing and is usually not a useful starting point.
*/
SET START_DATE = '2025-04-01';
SET END_DATE = '2026-03-31';
SET BNF_PREFIX = '0403';
SET VTM_SNOMED_CODE = NULL;
SET VMP_SNOMED_CODE = NULL;
SET TOP_N = 100;
WITH products AS (
-- Keep at least one of the filters below populated so the product set is intentional.
SELECT DISTINCT
"ProductSnomedCode",
"ProductDescription",
"TherapeuticMoietyName",
"BNFCode",
"BNFParagraphCode"
FROM DATA_HUB.DWH."DimMedicineAndDevice"
WHERE ($BNF_PREFIX IS NOT NULL AND "BNFCode" LIKE $BNF_PREFIX || '%')
OR ($VTM_SNOMED_CODE IS NOT NULL AND "TherapeuticMoietySnomedCode" = $VTM_SNOMED_CODE)
OR ($VMP_SNOMED_CODE IS NOT NULL AND "MedicinalLatestSnomedCode" = $VMP_SNOMED_CODE)
),
patient_costs AS (
-- Aggregate first at patient/practice level so ranking is not inflated by joins.
SELECT
rx."PersonKey",
rx."CurrentGeneralPractice" AS "PracticeCode",
COUNT(*) AS "PrescriptionRows",
COUNT(DISTINCT prod."ProductSnomedCode") AS "DistinctProducts",
SUM(COALESCE(rx."EstPrice", 0)) AS "EstimatedCost"
FROM REPORTING_DATASETS_ICB.SCRATCHPAD."MEDS__UnifiedPrescribingTable" rx
INNER JOIN products prod
ON rx."SNOMEDCode" = prod."ProductSnomedCode"
WHERE rx."DateMedicationStart" BETWEEN $START_DATE AND $END_DATE
AND rx."PersonKey" IS NOT NULL
GROUP BY rx."PersonKey", rx."CurrentGeneralPractice"
),
practice_lookup AS (
-- De-duplicated practice labels prevent site-level duplicates in the ranking output.
SELECT
"OrganisationCode" AS "PracticeCode",
MIN("OrganisationName") AS "PracticeName",
MIN("PCNName") AS "PCNName",
MIN("PlaceName") AS "PlaceName",
MIN("AllianceName") AS "AllianceName"
FROM DATA_HUB.DWH."DimOrganisationAndSite"
WHERE "OrganisationSubType" = 'GP Practice'
AND "IsSiteActive" = 'Yes'
AND "IsSiteNorfolkAndSuffolk" = 'Yes'
AND "SiteCode" = "OrganisationCode"
GROUP BY "OrganisationCode"
),
ranked AS (
SELECT
ROW_NUMBER() OVER (ORDER BY pc."EstimatedCost" DESC NULLS LAST) AS "Rank",
gp."PracticeName",
gp."PCNName",
gp."PlaceName",
gp."AllianceName",
pc."PersonKey",
pc."PracticeCode",
pc."PrescriptionRows",
pc."DistinctProducts",
pc."EstimatedCost"
FROM patient_costs pc
INNER JOIN practice_lookup gp
ON pc."PracticeCode" = gp."PracticeCode"
)
SELECT
"Rank",
"PracticeName",
"PCNName",
"PlaceName",
"AllianceName",
"PersonKey",
"PracticeCode",
"PrescriptionRows",
"DistinctProducts",
"EstimatedCost"
FROM ranked
WHERE "Rank" <= $TOP_N
ORDER BY "Rank";