Master your fehr
Part IV
Lara Hopley
Jo van Schalkwyk
www.fehr.org
Where are we?
Part I: Some philosophy
Part II: Get it working
<tea>
Part III: The anatomy of fehr
Part IV: Experimentation
fehr.org
Basic SQL operations
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE
INSERT INTO
SELECT … FROM
GROUP BY
ORDER BY
INNER JOIN
OUTER JOIN (and nulls)
fehr.org
(now)
0. Back up your database
fehr.org
Make a convenient directory eg fehr/testing and go there
From the command line:
Mac:
/Applications/MAMP/Library/bin/mysqldump -u
root -p fehr > fehr_full_backup.sql
Windows:
mysqldump -u root -p fehr >
fehr_full_backup.sql
And restore (DANGER!!!)
fehr.org
drop schema fehr; -- will irreversibly destroy entire database
create database fehr CHARACTER SET=utf8
COLLATE=utf8_general_ci;
use fehr;
source ~/fehr/testing/fehr_full_backup.sql
Let’s load another copy
Here’s one I prepared before …
source ~/fehr/testing/fehr_and_pain.sql
fehr.org
1. CREATE TABLE
fehr.org
We’ll create a table called ANON …
… and populate it with some data on anaphylaxis to neuromuscular
blockers we published last year
CREATE TABLE ANON
( DrugName varchar(64)
,NHI integer -- anonymise NHI
,bad_nhi integer
,suspect_data integer
,CreationTime integer -- year only
,AnaestheticId integer -- anonymise AnaestheticId
,NotAdministeredReasonId integer
,Delta integer -- time difference as above
,ScannedBarCodeNumber varchar(20)
,Dose integer
,DoseUnit varchar(16)
,IsInfusion varchar(5)
,InfusionRate integer
,InfusionRateUnit varchar(16)
,IsBolus varchar(5)
,WasRepeated varchar(5)
,DHB integer
,Excluded integer);
fehr.org
1a. Okay, that needs some work
Navigate to fehr/testing
Open supp_mac.txt or supp_windows.txt in Nano | Notepad
Copy the lot
Log into SQL from the command line, as root
Say use fehr;
Paste everything into the console
fehr.org
There are over 20 examples
Consult the document supplement2.docx
fehr.org
2. INSERT INTO …
Along the lines of:
INSERT INTO ANON (DrugName, NHI, bad_nhi)
VALUES ('Rocuronium‘, 1234, 0);
fehr.org
3. SELECT
SELECT COUNT(1) FROM ANON;
SELECT * FROM ANON LIMIT 0,10;
SELECT DrugName, CreationTime, AnaestheticId, Dose, DoseUnit
FROM ANON WHERE bad_nhi = 0 limit 0,20;
fehr.org
4. GROUP BY
SELECT DHB ,count(DISTINCT AnaestheticId)
FROM `ANON`
GROUP BY DHB;
fehr.org
5. ORDER BY
SELECT
DrugName
,DHB
,count(DISTINCT AnaestheticId) as Anaesthetics
FROM ANON
WHERE Excluded = 0
GROUP BY DrugName ,DHB
ORDER BY DrugName ,DHB;
fehr.org
6. INNER JOIN
fehr.org
Here we’ll use the main database. Let’s do a bit of scouting:
SELECT * FROM PROCESSES LIMIT 0,1;
SELECT DISTINCT dd_patient FROM PROCESSES;
SELECT * FROM PROCESSES WHERE dd_patient = 3001 LIMIT 0,1;
SELECT process, GT(t_amended), process_type FROM PROCESSES
WHERE dd_patient = 3001;
7. LEFT OUTER JOIN
SELECT
prt.description
,GT(proc.t_amended)
,proc.process
FROM PROCESSES proc
LEFT JOIN process_types prt
ON prt.process_type = proc.process_type
WHERE proc.dd_patient = 3001;
fehr.org
INNER JOIN (continued)
SELECT
prt.description
,GT(proc.t_amended)
,proc.process
FROM PROCESSES proc
INNER JOIN process_types prt
ON prt.process_type = proc.process_type
WHERE proc.dd_patient = 3001;
fehr.org
8. This can become rather complex
SELECT * FROM
PROCESSES proc
INNER JOIN EPOCHS epo
ON proc.process = epo.process
INNER JOIN INTERVENTIONS intrv
ON intrv.epoch = epo.epoch
INNER JOIN RESULTS reslt
ON reslt.intervention = intrv.intervention;
fehr.org
9. Writing efficient SQL queries
A black art
Needs lots of practice
There are a few things we can do to make it better
fehr.org
10. Better queries
Standardised and validated queries
Wrap the queries in a “GUI”
• This is what Wholly does
• Wholly also allows local manipulation of table data
An idea I’ve been playing with: Vector sequel
• Suck in an entire column of data using “ODBC”
• About 8 simple commands deal with ‘columns at a time’
• Writes to the fehr database
fehr.org
The End.
fehr.org
© Copyright 2026 Paperzz