This article is part of a series: OpenPrescribing measure development

Here at we spend time making sure that our measures remain up-to-date, accurate, and relevant. We also consider how our measure definitions are written in a way that, where possible, automatically picks up new medicines or formulations without the need for the team to manually curate them. We’ve previously described the ways we can now do this using the features available in the dictionary of medicines and devices (dm+d) in a previous blog.

In this short series on recent measure development we’re going to describe the measures we’ve changed, what we’ve done, and why.

(Author’s note: this blog contains lots of SQL, please feel free to skip over it!)

“Items which shouldn’t be routinely prescribed in primary care”

In August 2023 NHS published a comprehensive update to their Items which shouldn’t be routinely prescribed in primary care guidance, including significant changes to the wording, and some changes to the drugs included. The guidance on tadalafil daily prescribing has been removed completely.

This prompted the biggest review amongst all of our recent housekeeping. We had measures relating to NHS England guidance on medicines of “low priority” as far back as the original consultation in 2017, with a full set of measures relating to all 25 topics available since 2018.

We’ve therefore taken the opportunity to review all 25 24 measures (minus tadalafil), align the wording with the new NHS England guidance, and redesign the measure definitions. We have also taken this opportunity to improve the finding of new formulations where we can, including in bath & shower emollients and fentanyl immediate release preparations - and you can see examples of how we’ve changed how we code below.

You can find all of the measures on, but here are some of the most significant changes:

Bath and shower emollients

This is quite a challenging measure to keep up-to-date, as the products are included in various parts of the BNF coding system, in both “skin” and “appliances”, which makes automatically identifying new products more difficult than usual.

We’ve created a measure which looks at both codes and names, to find the products without having to keep a fully up-to-date list.

  LOWER(presentation) NOT LIKE '%shampoo%' #exclude all shampoos
    presentation_code LIKE '1302011%' AND # include all Emollient Bath & Shower Preparation
    presentation_code NOT LIKE '130201100%AM' #exclude Aqueous Cream (brand and generics)
      presentation_code LIKE '130201000%' OR # include Other emollient preparations (with forms listed below)
      presentation_code LIKE '1902055%' OR # include Toiletries (with forms listed below)
      presentation_code LIKE '2122%' # include Emollients (with forms listed below)
        LOWER(presentation) LIKE '%bath%' OR # include formulations with bath in name
        LOWER(presentation) LIKE '%wash%' OR # include formulations with wash in name
        LOWER(presentation) LIKE '%shower%' # include formulations with shower in name

        LOWER(presentation) NOT LIKE '%wash cap%' AND # exclude wash caps
        LOWER(presentation) NOT LIKE '%wash mitts%' AND # exclude wash mitts
        LOWER(presentation) NOT LIKE '%antimicrobial%'AND # exclude formulations with antimicrobial in name
        LOWER(presentation) NOT LIKE '%feminine%' # exclude formulations with feminine in name

(From a CPD perspective, none of the clinical informaticans at the Bennett Institute were aware of the availability of wash caps or wash mitts on primary care prescriptions until now.)

Fentanyl immediate release

To improve this measure, we have now used the dm+d structure to filter fentanyl products, removing any patches and parenteral products, only leaving the immediate release preparations in the measure. Once again, this allows us to pick up new formulations automatically:

v.dform_form NOT IN ('Transdermal patch','Solution for infusion','Infusion','Solution for injection')

Herbal medicines

Rewriting this measure definition created a bit of a challenge for us.

In the old version of the measure we used a simple flag in dm+d to identify where a product had a traditional herbal registration (THR). The new guidance has expanded the number of medicines included to include:

other natural products without robust evidence of clinical effectiveness…(which) are not recognised as supplements in the NHS Drug Tariff and do not appear as medicines in the BNF. These include natural oils, e.g. eucalyptus and almond, coenzyme Q10 (ubiquinone and ubidecarenone, and evening primrose (gamolenic acid).

We have now included the majority of these preparations, but we’re still working on how to identify natural oils. As soon as this work is completed we will update the measure.

Paracetamol and tramadol combinations

We have updated this measure definition to use the Virtual Therapeutic Moiety (VTM) function in dm+d. This allows us to use a single code (777074005) to find both generic (Virtual Medicinal Product - “VMP”) and brands (Actual Medicinal Product - “AMP”) automatically, regardless of how they are coded in the BNF coding system:

SELECT DISTINCT v.bnf_code FROM dmd.vmp v
INNER JOIN dmd.vtm t ON = v.vtm
WHERE --VTM for paracetamol and tramadol
AND v.bnf_code IS NOT NULL
SELECT DISTINCT a.bnf_code FROM dmd.amp a
INNER JOIN dmd.vmp v ON a.vmp =
INNER JOIN dmd.vtm t ON = v.vtm
AND a.bnf_code IS NOT NULL

This means that if there are any new products, this measure will now automatically pick them up.

NHS England Medicines Optimisation Opportunities

We’ve already written about this in a previous blog, but in summary: we’ve brought together a number of measures into a single ‘National Medicines Optimisation Opportunities’ tag, so you can find them all in one place. They include:

Urinary Tract Infection duration

Some of our very first measures back in 2016 were related to antibiotics, including one on the use of a 3-day course in uncomplicated urinary tract infections (UITs) in appropriate situations, which used the average daily quantity. We have taken the opportunity to revise this in the last few months, and it now describes the proportion of prescriptions for commonly used UTI treatments which are prescribed for a 3-day length. We feel this is now a more accurate way of measuring this topic.

Continuous Glucose Monitoring (CGM) sensors

The original measure only looked at Freestyle Libre, which was the only CGM monitor available at the time. Since then our measure has now been updated twice: once to automatically include all CGM meters introduced since, and then again to ensure that CGM _transmitters _are not included.

We have done this with a combination of using a VMP code and looking for the word “transmitter”.

SELECT bnf_code FROM dmd.vmp
id = 34865511000001109
LOWER(nm) NOT LIKE '%transmitter%' -- selects bnf_codes from vmp table matching VMP id, excluding transmitters
UNION DISTINCT -- joins vmp and amp tables together
SELECT bnf_code FROM dmd.amp 
vmp = 34865511000001109
bnf_code IS NOT NULL AND LOWER(nm) NOT LIKE '%transmitter%') bnf -- selects bnf_codes from amp table matching VMP id where they exist, excluding transmitters


We currently have several measures regarding gabapentinoids, including the total Defined Daily Dose (DDD) for both pregabalin and gabapentin, as well as the total milligrams of pregabalin. We were finding that new preparations (for example pregabalin tablets) were not being included in the measure. We’ve taken the opportunity to use some of the features of dm+d to resolve this. The strength of each formulation is recorded in dm+d, and by using this with a simple calculation we can calculate the total units prescribed in milligrams. Then by using the standard DDD values associated with the ingredient code, we can derive the total DDD’s prescribed automatically, without the need to update when new formulations come on the market:

SUM((p.quantity * i.strnt_nmrtr_val * COALESCE(n.nmtr_unit_conversion,1) / -- calculate the total unit of drug, and convert if necessary to milligrams). Uses COALESCE to default to 1 if conversion not available
COALESCE(d.nmtr_unit_conversion * i.strnt_dnmtr_val,1) / --divides unit dose if multiple, and converts to millilitre if necessary. Uses COALESCE to default to 1 if conversion or denominator strength not available
CASE WHEN p.bnf_code LIKE '0408010AE%' THEN 300 ELSE 1800 END)) AS numerator -- divide number of milligram by 300 (pregabalin) or 1800 (gabapentin) to get DDD
p.bnf_code LIKE '0408010AE%' --Pregabalin
OR p.bnf_code LIKE '0408010G0%') --Gabapentin
    415160008, --Pregabalin ing_code
    386845007) --Gabapentin ing_code

Please get in touch!

As always at the Bennett Institute we work in the open as much as we can. All of our measure definitions are available openly on Github, and we include a “View technical details for this measure” link on each measure. Using ourCow’s Milk Protein Allergy measure as an example you can find:

  • the SQL used to produce the measure,
  • a link to the change history
  • who in the team wrote and checked the measure
  • when it was last reviewed
  • whether there was any Jupyter notebook created as part of its development.

We really appreciate feedback from our users. You help us find errors and suggest improvements to existing measures, as well as inspiring the development of new ones. We will be writing shortly about our measure development process, and what makes a useful and successful (and not-so-successful) measure.

If you have any comments or suggestions for any part of OpenPrescribing please do not hesitate to get in touch with us, either by email or tagging us on X (formerly Twitter).