initial commit
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
High-prescribing practice quintile template
|
||||
===========================================
|
||||
|
||||
Purpose:
|
||||
Identify practices in the highest quintile for one or more prescribing
|
||||
measures after standardising by registered population.
|
||||
|
||||
Based on the antidepressant high-prescribing analysis, but made generic:
|
||||
- Replace medicine_products with the medicine definition you need.
|
||||
- Add/remove measures in practice_counts and final_select.
|
||||
- Keep the practice and base_population CTEs visible so geography and
|
||||
denominator decisions are explicit.
|
||||
*/
|
||||
|
||||
SET START_DATE = '2025-04-01';
|
||||
SET END_DATE = '2026-03-31';
|
||||
SET BNF_PREFIX = 'REPLACE_WITH_BNF_PREFIX';
|
||||
SET REPORT_TITLE = 'REPLACE_WITH_REPORT_NAME';
|
||||
|
||||
WITH practices AS (
|
||||
-- Practice list and hierarchy columns used in the final report.
|
||||
SELECT DISTINCT
|
||||
"OrganisationCode" AS "PracticeCode",
|
||||
"OrganisationName" AS "PracticeName",
|
||||
"PCNName",
|
||||
"PlaceName",
|
||||
"AllianceName",
|
||||
"INTName",
|
||||
"RegisteredPopulation" AS "OrganisationRegisteredPopulation",
|
||||
"RegisteredPopulationSnapshotDate" AS "OrganisationPopulationSnapshotDate"
|
||||
FROM DATA_HUB.DWH."DimOrganisationAndSite"
|
||||
WHERE "OrganisationSubType" = 'GP Practice'
|
||||
AND "IsSiteActive" = 'Yes'
|
||||
AND "IsSiteNorfolkAndSuffolk" = 'Yes'
|
||||
AND "SiteCode" = "OrganisationCode"
|
||||
),
|
||||
base_population AS (
|
||||
-- Counted denominator: active, known, living patients currently registered to the practice.
|
||||
SELECT
|
||||
p."PracticeCode",
|
||||
dp."PersonKey",
|
||||
dp."PatientPseudonym",
|
||||
dp."CurrentAge",
|
||||
dp."BAME"
|
||||
FROM DATA_HUB.DWH."DimPerson" dp
|
||||
INNER JOIN practices p
|
||||
ON dp."CurrentGeneralPractice" = p."PracticeCode"
|
||||
WHERE dp."RecordStatus" = 'Active'
|
||||
AND dp."PersonStatus" = 'Known'
|
||||
AND dp."CurrentGeneralPractice" IS NOT NULL
|
||||
AND dp."CurrentGeneralPractice" <> '*'
|
||||
AND dp."YearMonthDeath" IS NULL
|
||||
),
|
||||
practice_population AS (
|
||||
SELECT
|
||||
"PracticeCode",
|
||||
COUNT(DISTINCT "PersonKey") AS "RegisteredPatients"
|
||||
FROM base_population
|
||||
GROUP BY "PracticeCode"
|
||||
),
|
||||
medicine_products AS (
|
||||
-- Replace this with a VTM/VMP/explicit-code definition if BNF is too broad.
|
||||
SELECT DISTINCT
|
||||
"ProductSnomedCode"
|
||||
FROM DATA_HUB.DWH."DimMedicineAndDevice"
|
||||
WHERE "ProductSnomedCode" IS NOT NULL
|
||||
AND "BNFCode" LIKE $BNF_PREFIX || '%'
|
||||
),
|
||||
medicine_patients AS (
|
||||
-- Patient-level numerator cohort before practice aggregation.
|
||||
SELECT DISTINCT
|
||||
bp."PracticeCode",
|
||||
bp."PersonKey",
|
||||
bp."PatientPseudonym",
|
||||
bp."CurrentAge",
|
||||
bp."BAME"
|
||||
FROM REPORTING_DATASETS_ICB.SCRATCHPAD."MEDS__UnifiedPrescribingTable" rx
|
||||
INNER JOIN base_population bp
|
||||
ON rx."PersonKey" = bp."PersonKey"
|
||||
INNER JOIN medicine_products mp
|
||||
ON rx."SNOMEDCode" = mp."ProductSnomedCode"
|
||||
WHERE rx."DateMedicationStart" BETWEEN $START_DATE AND $END_DATE
|
||||
AND rx."PersonKey" IS NOT NULL
|
||||
),
|
||||
practice_counts AS (
|
||||
-- Add or remove measure columns here, then mirror them in final_select.
|
||||
SELECT
|
||||
"PracticeCode",
|
||||
COUNT(DISTINCT "PersonKey") AS "PatientsOnMedicine",
|
||||
COUNT(DISTINCT CASE WHEN "CurrentAge" > 65 THEN "PersonKey" END) AS "PatientsOnMedicineAgedOver65",
|
||||
COUNT(DISTINCT CASE WHEN "CurrentAge" > 85 THEN "PersonKey" END) AS "PatientsOnMedicineAgedOver85",
|
||||
COUNT(DISTINCT CASE WHEN "BAME" = 'BAME' THEN "PersonKey" END) AS "PatientsOnMedicineEthnicMinority"
|
||||
FROM medicine_patients
|
||||
GROUP BY "PracticeCode"
|
||||
),
|
||||
final_select AS (
|
||||
-- Per-1000 rates use the counted patient denominator from base_population.
|
||||
SELECT
|
||||
$REPORT_TITLE AS "ReportTitle",
|
||||
$START_DATE::DATE AS "PeriodStartDate",
|
||||
$END_DATE::DATE AS "PeriodEndDate",
|
||||
p."PracticeCode",
|
||||
p."PracticeName",
|
||||
p."PCNName",
|
||||
p."PlaceName",
|
||||
p."AllianceName",
|
||||
p."INTName",
|
||||
pop."RegisteredPatients",
|
||||
p."OrganisationRegisteredPopulation",
|
||||
p."OrganisationPopulationSnapshotDate",
|
||||
COALESCE(pc."PatientsOnMedicine", 0) AS "PatientsOnMedicine",
|
||||
ROUND(1000.0 * COALESCE(pc."PatientsOnMedicine", 0) / NULLIF(pop."RegisteredPatients", 0), 2) AS "PatientsOnMedicinePer1000",
|
||||
COALESCE(pc."PatientsOnMedicineAgedOver65", 0) AS "PatientsOnMedicineAgedOver65",
|
||||
ROUND(1000.0 * COALESCE(pc."PatientsOnMedicineAgedOver65", 0) / NULLIF(pop."RegisteredPatients", 0), 2) AS "PatientsOnMedicineAgedOver65Per1000",
|
||||
COALESCE(pc."PatientsOnMedicineAgedOver85", 0) AS "PatientsOnMedicineAgedOver85",
|
||||
ROUND(1000.0 * COALESCE(pc."PatientsOnMedicineAgedOver85", 0) / NULLIF(pop."RegisteredPatients", 0), 2) AS "PatientsOnMedicineAgedOver85Per1000",
|
||||
COALESCE(pc."PatientsOnMedicineEthnicMinority", 0) AS "PatientsOnMedicineEthnicMinority",
|
||||
ROUND(1000.0 * COALESCE(pc."PatientsOnMedicineEthnicMinority", 0) / NULLIF(pop."RegisteredPatients", 0), 2) AS "PatientsOnMedicineEthnicMinorityPer1000"
|
||||
FROM practices p
|
||||
INNER JOIN practice_population pop
|
||||
ON p."PracticeCode" = pop."PracticeCode"
|
||||
LEFT JOIN practice_counts pc
|
||||
ON p."PracticeCode" = pc."PracticeCode"
|
||||
),
|
||||
with_quintiles AS (
|
||||
-- Quintile 5 is the highest rate in each measure.
|
||||
SELECT
|
||||
"ReportTitle",
|
||||
"PeriodStartDate",
|
||||
"PeriodEndDate",
|
||||
"PracticeCode",
|
||||
"PracticeName",
|
||||
"PCNName",
|
||||
"PlaceName",
|
||||
"AllianceName",
|
||||
"INTName",
|
||||
"RegisteredPatients",
|
||||
"OrganisationRegisteredPopulation",
|
||||
"OrganisationPopulationSnapshotDate",
|
||||
"PatientsOnMedicine",
|
||||
"PatientsOnMedicinePer1000",
|
||||
"PatientsOnMedicineAgedOver65",
|
||||
"PatientsOnMedicineAgedOver65Per1000",
|
||||
"PatientsOnMedicineAgedOver85",
|
||||
"PatientsOnMedicineAgedOver85Per1000",
|
||||
"PatientsOnMedicineEthnicMinority",
|
||||
"PatientsOnMedicineEthnicMinorityPer1000",
|
||||
NTILE(5) OVER (ORDER BY "PatientsOnMedicinePer1000") AS "PatientsOnMedicineQuintile",
|
||||
NTILE(5) OVER (ORDER BY "PatientsOnMedicineAgedOver65Per1000") AS "AgedOver65Quintile",
|
||||
NTILE(5) OVER (ORDER BY "PatientsOnMedicineAgedOver85Per1000") AS "AgedOver85Quintile",
|
||||
NTILE(5) OVER (ORDER BY "PatientsOnMedicineEthnicMinorityPer1000") AS "EthnicMinorityQuintile"
|
||||
FROM final_select
|
||||
)
|
||||
SELECT
|
||||
"ReportTitle",
|
||||
"PeriodStartDate",
|
||||
"PeriodEndDate",
|
||||
"PracticeCode",
|
||||
"PracticeName",
|
||||
"PCNName",
|
||||
"PlaceName",
|
||||
"AllianceName",
|
||||
"INTName",
|
||||
"RegisteredPatients",
|
||||
"OrganisationRegisteredPopulation",
|
||||
"OrganisationPopulationSnapshotDate",
|
||||
"PatientsOnMedicine",
|
||||
"PatientsOnMedicinePer1000",
|
||||
"PatientsOnMedicineQuintile",
|
||||
"PatientsOnMedicineAgedOver65",
|
||||
"PatientsOnMedicineAgedOver65Per1000",
|
||||
"AgedOver65Quintile",
|
||||
"PatientsOnMedicineAgedOver85",
|
||||
"PatientsOnMedicineAgedOver85Per1000",
|
||||
"AgedOver85Quintile",
|
||||
"PatientsOnMedicineEthnicMinority",
|
||||
"PatientsOnMedicineEthnicMinorityPer1000",
|
||||
"EthnicMinorityQuintile"
|
||||
FROM with_quintiles
|
||||
WHERE "PatientsOnMedicineQuintile" = 5
|
||||
OR "AgedOver65Quintile" = 5
|
||||
OR "AgedOver85Quintile" = 5
|
||||
OR "EthnicMinorityQuintile" = 5
|
||||
ORDER BY
|
||||
"PatientsOnMedicinePer1000" DESC,
|
||||
"PracticeName";
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Practice-level prescribing summary by BNF prefix
|
||||
================================================
|
||||
|
||||
Purpose:
|
||||
Produce a compact practice/month summary for prescribing under a BNF prefix.
|
||||
|
||||
Good first query for:
|
||||
- "How much prescribing activity is there for this BNF section?"
|
||||
- "Which practices have the most patients/items/cost for this medicine area?"
|
||||
- A simple numerator for charts or practice packs.
|
||||
*/
|
||||
|
||||
SET START_DATE = '2025-04-01';
|
||||
SET END_DATE = '2026-03-31';
|
||||
SET BNF_PREFIX = '0403';
|
||||
|
||||
WITH practices AS (
|
||||
-- Default reporting geography: active Norfolk and Suffolk parent GP practices.
|
||||
SELECT DISTINCT
|
||||
"OrganisationCode" AS "PracticeCode",
|
||||
"OrganisationName" AS "PracticeName",
|
||||
"PCNName",
|
||||
"PlaceName",
|
||||
"AllianceName"
|
||||
FROM DATA_HUB.DWH."DimOrganisationAndSite"
|
||||
WHERE "OrganisationSubType" = 'GP Practice'
|
||||
AND "IsSiteActive" = 'Yes'
|
||||
AND "IsSiteNorfolkAndSuffolk" = 'Yes'
|
||||
AND "SiteCode" = "OrganisationCode"
|
||||
),
|
||||
prescribing AS (
|
||||
-- Aggregate after joining to the medicine dimension so BNF matching is dm+d-backed.
|
||||
SELECT
|
||||
DATE_TRUNC('MONTH', rx."DateMedicationStart")::DATE AS "MonthStartDate",
|
||||
p."PracticeCode",
|
||||
p."PracticeName",
|
||||
p."PCNName",
|
||||
p."PlaceName",
|
||||
p."AllianceName",
|
||||
med."BNFParagraphCode",
|
||||
COUNT(DISTINCT rx."PersonKey") AS "Patients",
|
||||
COUNT(*) AS "PrescriptionRows",
|
||||
SUM(TRY_CAST(rx."Quantity" AS FLOAT)) AS "TotalQuantity",
|
||||
SUM(rx."EstPrice") AS "EstimatedCost"
|
||||
FROM REPORTING_DATASETS_ICB.SCRATCHPAD."MEDS__UnifiedPrescribingTable" rx
|
||||
INNER JOIN DATA_HUB.DWH."DimMedicineAndDevice" med
|
||||
ON rx."SNOMEDCode" = med."ProductSnomedCode"
|
||||
AND med."BNFCode" LIKE $BNF_PREFIX || '%'
|
||||
INNER JOIN practices p
|
||||
ON rx."CurrentGeneralPractice" = p."PracticeCode"
|
||||
WHERE rx."DateMedicationStart" BETWEEN $START_DATE AND $END_DATE
|
||||
AND rx."PersonKey" IS NOT NULL
|
||||
GROUP BY
|
||||
DATE_TRUNC('MONTH', rx."DateMedicationStart")::DATE,
|
||||
p."PracticeCode",
|
||||
p."PracticeName",
|
||||
p."PCNName",
|
||||
p."PlaceName",
|
||||
p."AllianceName",
|
||||
med."BNFParagraphCode"
|
||||
)
|
||||
SELECT
|
||||
"MonthStartDate",
|
||||
"PracticeCode",
|
||||
"PracticeName",
|
||||
"PCNName",
|
||||
"PlaceName",
|
||||
"AllianceName",
|
||||
"BNFParagraphCode",
|
||||
"Patients",
|
||||
"PrescriptionRows",
|
||||
"TotalQuantity",
|
||||
"EstimatedCost"
|
||||
FROM prescribing
|
||||
ORDER BY
|
||||
"MonthStartDate",
|
||||
"PracticeName",
|
||||
"BNFParagraphCode";
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
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";
|
||||
Reference in New Issue
Block a user