Repository navigation
Expand file tree
/
Copy path05_RISK_FACTOR_ALGORITHMS.sql
More file actions
2705 lines (2470 loc) · 103 KB
/
Copy path05_RISK_FACTOR_ALGORITHMS.sql
File metadata and controls
2705 lines (2470 loc) · 103 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
--
--
------------------------------------------
--
-- DISABLE AUTO-COMMIT BEFORE RUNNING THIS SCRIPT
--
-- ENABLE ONCE COMPLETE
--
------------------------------------------
--
-- Script: 05_RISK_FACTOR_ALGORITHMS.sql
-- SAIL project: 1483 - Cardiovascular disease risk prediction and optimisation of risk factor management
--
-- About: Running algorithms for identifying primary care records for smoking history, and primary and secondary care records for BMI
-- Author: Daniel King
------------------------------------------
--
-- BMI Algorithm
------------------------------------------
--
-- Code by: m.j.childs@swansea.ac.uk
-- Modified from code by: s.j.aldridge@swansea.ac.uk
--
-- Extracting all BMI related entries between 2000-2023.
-----------------------------------------------------------------------------------------------------------------
-- CREATE AN ALIAS FOR THE MOST RECENT VERSIONS OF THE WLGP AND PEDW EVENT TABLES AS BELOW:
CREATE OR REPLACE ALIAS SAILW1483V.BMI_ALG_GP
FOR SAILW1483V.EXTRACT_P2_WLGP_GP_EVENT_CLEANSED ;
--
CREATE OR REPLACE ALIAS SAILW1483V.BMI_ALG_PEDW_SPELL
FOR SAILW1483V.EXTRACT_P2_PEDW_SPELL ;
--
CREATE OR REPLACE ALIAS SAILW1483V.BMI_ALG_PEDW_DIAG
FOR SAILW1483V.EXTRACT_P2_PEDW_DIAG ;
--
CREATE OR REPLACE ALIAS SAILW1483V.BMI_ALG_WDSD
FOR SAILW1483V.EXTRACT_P2_WDSD_PER_RESIDENCE_GPREG ;
--
-----------------------------------------------------------------------------------------------------------------
-- CREATE VARIABLES FOR THE EARLIEST AND LATEST DATES YOU WANT THE BMI VALUES FOR (REPLACE DATES AS NECESSARY)
CREATE OR REPLACE VARIABLE SAILW1483V.BMI_DATE_FROM DATE;
SET SAILW1483V.BMI_DATE_FROM = '2000-01-01' ; -- 'YYYY-MM-DD'
CREATE OR REPLACE VARIABLE SAILW1483V.BMI_DATE_TO DATE;
SET SAILW1483V.BMI_DATE_TO = '2023-12-31' ; -- 'YYYY-MM-DD'
--5. OPTIONAL -- ASSIGN YOUR ACCEPTABLE RANGES FOR BMI AT:
-- SAME DAY VARIATION - DEFAULT = 0.05
CREATE OR REPLACE VARIABLE SAILW1483V.BMI_SAME_DAY DOUBLE DEFAULT 0.05;
-- RATE OF CHANGE - DEFAULT = 0.003
CREATE OR REPLACE VARIABLE SAILW1483V.BMI_RATE DOUBLE DEFAULT 0.003;
-----------------------------------------------------------------------------------------------------------------
-- OPTIONAL --- CREATE LOOKUP TABLE
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_LOOKUP');
CREATE TABLE SAILW1483V.BMI_LOOKUP
(
BMI_CODE CHAR(5),
DESCRIPTION VARCHAR(300),
COMPLEXITY VARCHAR(51),
CATEGORY VARCHAR(20)
);
--GRANTING ACCESS TO TEAM MATES
GRANT ALL ON TABLE SAILW1483V.BMI_LOOKUP TO ROLE NRDASAIL_SAIL_1483_ANALYST;
--WORTH DOING FOR LARGE CHUNKS OF DATA
ALTER TABLE SAILW1483V.BMI_LOOKUP ACTIVATE NOT LOGGED INITIALLY;
-- THIS LOOKUP TABLE CONTAINS THE GP LOOK UP CODES RELEVENT TO HEIGHT, WEIGHT AND BMI, THEY ARE CATEGORISED AS SUCH.
INSERT INTO SAILW1483V.BMI_LOOKUP
VALUES
('2293.', 'O/E -height within 10% average', 'where event_val between x and y (depending on unit)', 'height'),
('229..', 'O/E - height', 'where event_val between x and y (depending on unit)', 'height'),
('229Z.', 'O/E - height NOS', 'where event_val between x and y (depending on unit)', 'height'),
('2292.', 'O/E - height 10-20% < average', 'height', 'height'),
('2294.', 'O/E - height 10-20% over average', 'height', 'height'),
('2295.', 'O/E - height > 20% over average', 'height', 'height'),
('2291.', 'O/E - height > 20% below average', 'height', 'height'),
('22A..', 'O/E - weight', 'where event_val between 32 and 250', 'weight'),
('22A1.', 'O/E - weight > 20% below ideal', 'where event_val between 32 and 250', 'weight'),
('22A2.', 'O/E - weight 10-20% below ideal', 'where event_val between 32 and 250', 'weight'),
('22A3.', 'O/E - weight within 10% ideal', 'where event_val between 32 and 250', 'weight'),
('22A4.', 'O/E - weight 10-20% over ideal', 'where event_val between 32 and 250', 'weight'),
('22A5.', 'O/E - weight > 20% over ideal', 'where event_val between 32 and 250', 'weight'),
('22A6.', 'O/E - Underweight', 'where event_val between 32 and 250', 'weight'),
('22AA.', 'Overweight', 'where event_val between 32 and 250', 'weight'),
('22AZ.', 'O/E - weight NOS', 'where event_val between 32 and 250', 'weight'),
('1266.', 'FH: Obesity', 'Obese', 'obese'),
('1444.', 'H/O: obesity', 'Obese', 'obese'),
('22K3.', 'Body Mass Index low K/M2', 'Underweight', 'underweight'),
('22K..', 'Body Mass Index', 'BMI', 'BMI'),
('22K1.', 'Body Mass Index normal K/M2', 'Normal weight', 'normal weight'),
('22K2.', 'Body Mass Index high K/M2', 'Overweight/Obese', 'obese'),
('22K4.', 'Body mass index index 25-29 - overweight', 'Overweight', 'overweight'),
('22K5.', 'Body mass index 30+ - obesity', 'Obese', 'obese'),
('22K6.', 'Body mass index less than 20', 'Underweight', 'underweight'),
('22K7.', 'Body mass index 40+ - severely obese', 'Obese', 'obese'),
('22K8.', 'Body mass index 20-24 - normal', 'Normal weight', 'normal weight'),
('22K9.', 'Body mass index centile', 'BMI', 'BMI'),
('22KC.', 'Obese class I (body mass index 30.0 - 34.9)', 'Obese', 'obese'),
('22KC.', 'Obese class I (BMI 30.0-34.9)', 'Obese', 'obese'),
('22KD.', 'Obese class II (body mass index 35.0 - 39.9)', 'Obese', 'obese'),
('22KD.', 'Obese class II (BMI 35.0-39.9)', 'Obese', 'obese'),
('22KE.', 'Obese class III (BMI equal to or greater than 40.0)', 'Obese', 'obese'),
('22KE.', 'Obese cls III (BMI eq/gr 40.0)', 'Obese', 'obese'),
('66C4.', 'Has seen dietician - obesity', 'Obese', 'obese'),
('66C6.', 'Treatment of obesity started', 'Obese', 'obese'),
('66CE.', 'Reason for obesity therapy - occupational', 'Obese', 'obese'),
('8CV7.', 'Anti-obesity drug therapy commenced', 'Obese', 'obese'),
('8T11.', 'Rfrrl multidisip obesity clin', 'Obese', 'obese'),
('C38..', 'Obesity/oth hyperalimentation', 'Obese', 'obese'),
('C380.', 'Obesity', 'Obese', 'obese'),
('C3800', 'Obesity due to excess calories', 'Obese', 'obese'),
('C3801', 'Drug-induced obesity', 'Obese', 'obese'),
('C3802', 'Extrem obesity+alveol hypovent', 'Obese', 'obese'),
('C3803', 'Morbid obesity', 'Obese', 'obese'),
('C3804', 'Central obesity', 'Obese', 'obese'),
('C3805', 'Generalised obesity', 'Obese', 'obese'),
('C3806', 'Adult-onset obesity', 'Obese', 'obese'),
('C3807', 'Lifelong obesity', 'Obese', 'obese'),
('C38z.', 'Obesity/oth hyperalimentat NOS', 'Obese', 'obese'),
('C38z0', 'Simple obesity NOS', 'Obese', 'obese'),
('Cyu7.', '[X]Obesity+oth hyperalimentatn', 'Obese', 'obese'),
('22K4.', 'BMI 25-29 - overweight', 'Overweight', 'overweight'),
('22A1.', 'O/E - weight > 20% below ideal', 'Underweight', 'underweight'),
('22A2.', 'O/E -weight 10-20% below ideal', 'Underweight', 'underweight'),
('22A3.', 'O/E - weight within 10% ideal', 'Normal weight', 'normal weight'),
('22A4.', 'O/E - weight 10-20% over ideal', 'Overweight', 'overweight'),
('22A5.', 'O/E - weight > 20% over ideal', 'Overweight', 'overweight'),
('22A6.', 'O/E - Underweight', 'Underweight', 'underweight'),
('22AA.', 'Overweight', 'Overweight', 'overweight'),
('R0348', '[D] Underweight', 'Underweight', 'underweight'),
('66C1.','Itinital obesity assessment','Obese','obese'),
('66C2.','Follow-up obesity assessment','Obese','obese'),
('66C5.','Treatment of obesity changed','Obese','obese'),
('66CX.','Obesity multidisciplinary case review','Obese','obese'),
('66CZ.','Obesity monitoring NOS','Obese','obese'),
('9hN..','Exception reporting: obesity quality indicators','Obese','obese'),
('9OK..','Obesity monitoring admin.','Obese','obese'),
('9OK1.','Attends obesity monitoring','Obese','obese'),
('9OK3.','Obesity monitoring default','Obese','obese'),
('9OK2.','Refuses obesity monitoring','Obese','obese'),
('9OK4.','Obesity monitoring 1st letter','Obese','obese'),
('9OK5.','Obesity monitoring 2nd letter','Obese','obese'),
('9OK6.','Obesity monitoring 3rd letter','Obese','obese'),
('9OK7.','Obesity monitoring verbal inv.','Obese','obese'),
('9OK8.','Obesity monitor phone invite','Obese','obese'),
('9OKA.','Obesity monitoring check done','Obese','obese'),
('9OKZ.','Obesity monitoring admin.NOS','Obese','obese'),
('C38y0','Pickwickian syndrome','Obese','obese')
;
-- END OF READ CODES
-----------------------------------------------------------------------------------------------------------------
-- DROP FINAL BMI TABLE IF IT EXISTS USING THE CODE BELOW
-----------------------------------------------------------------------------------------------------------------
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_UNCLEAN_ADULTS_P2_DIABETES_ALL');
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_CLEAN_ADULTS_P2_DIABETES_ALL');
------------------------------------------------------------------------------------------------------------------
------------------------------- ALGORITHM RUNS FROM HERE ---------------------------------------------------------
------------------------------------------------------------------------------------------------------------------
--1. CREATING SUBTABLES OF BMI CATEGORY
-- THERE WILL BE A TABLE FOR UNDERWEIGHT, NORMAL WEIGHT, OVERWEIGHT, AND OBESE.
-- THESE WILL THEN BE PUT TOGETHER USING UNION ALL TO MAKE THE BMI_CAT TABLE.
------------------------------------------------------------------------------------------------------------------
--1A. TABLE FOR NORMAL UNDERWEIGHT
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.UNDERWEIGHT');
CREATE TABLE SAILW1483V.UNDERWEIGHT
(
ALF_PE BIGINT,
BMI_DT DATE,
BMI_CAT VARCHAR(13),
BMI_C CHAR(1),
BMI_VAL DECIMAL(5),
SOURCE_DB VARCHAR(12)
)
DISTRIBUTE BY HASH(ALF_PE);
COMMIT;
INSERT INTO SAILW1483V.UNDERWEIGHT
SELECT -- EXTRACTING THOSE CATEGORISED AS UNDERWEIGHT
DISTINCT (ALF_PE),
event_dt AS BMI_dt,
'Underweight' AS BMI_cat,
'1' AS BMI_c,
CASE
WHEN event_val >= 12 AND event_val < 18.50 THEN event_val
WHEN event_val IS NULL THEN NULL
ELSE 9999
END AS BMI_val,
'WLGP' AS source_db
FROM
SAILW1483V.BMI_ALG_GP a
INNER JOIN
SAILW1483V.BMI_lookup b
ON a.event_cd = b.BMI_code AND b.category = 'underweight'
WHERE
a.event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO
AND alf_sts_cd IN ('1', '4', '39')
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
;
COMMIT;
--1b. table for normal weight
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.NORMALWEIGHT');
CREATE TABLE SAILW1483V.NORMALWEIGHT
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_cat VARCHAR(13),
BMI_c CHAR(1),
BMI_val DECIMAL(5),
source_db VARCHAR(12)
)
DISTRIBUTE BY HASH(ALF_PE);
COMMIT;
INSERT INTO SAILW1483V.NORMALWEIGHT
SELECT
DISTINCT (ALF_PE),
event_dt AS BMI_dt,
'Normal weight' AS BMI_cat,
'2' AS BMI_c,
CASE
WHEN event_val >= 18.5 AND event_val < 25 THEN event_val
WHEN event_val IS NULL THEN NULL
ELSE 9999
END AS BMI_val,
'WLGP' AS source_db
FROM
SAILW1483V.BMI_ALG_GP a
RIGHT JOIN
SAILW1483V.BMI_lookup b
ON a.event_cd = b.BMI_code AND b.category = 'normal weight'
WHERE
a.event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO
AND alf_sts_cd IN ('1', '4', '39')
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
;
--1c. creating table for overweight
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.OVERWEIGHT');
CREATE TABLE SAILW1483V.OVERWEIGHT
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_cat VARCHAR(13),
BMI_c CHAR(1),
BMI_val DECIMAL(5),
source_db VARCHAR(12)
)
DISTRIBUTE BY HASH(ALF_PE);
COMMIT;
INSERT INTO SAILW1483V.OVERWEIGHT
SELECT
DISTINCT (ALF_PE),
event_dt AS BMI_dt,
'Overweight' AS BMI_cat,
'3' AS BMI_c,
CASE
WHEN event_val >= 25 AND event_val < 30 THEN event_val
WHEN event_val IS NULL THEN NULL
ELSE 9999
END AS BMI_val,
'WLGP' AS source_db
FROM
SAILW1483V.BMI_ALG_GP a
RIGHT JOIN
SAILW1483V.BMI_lookup b
ON a.event_cd = b.BMI_code AND b.category = 'overweight'
WHERE
a.event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO
AND alf_sts_cd IN ('1', '4', '39')
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
;
COMMIT;
--1d. creating table for obese
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.OBESE');
CREATE TABLE SAILW1483V.OBESE
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_cat VARCHAR(13),
BMI_c CHAR(1),
BMI_val DECIMAL(5),
source_db VARCHAR(12)
)
DISTRIBUTE BY HASH(ALF_PE);
COMMIT;
ALTER TABLE SAILW1483V.OBESE activate not logged INITIALLY;
INSERT INTO SAILW1483V.OBESE
SELECT
DISTINCT (ALF_PE),
event_dt AS BMI_dt,
'Obese' AS BMI_cat,
'4' AS BMI_c,
CASE
WHEN event_val > 30 AND event_val < 100 THEN event_val
WHEN event_val IS NULL THEN NULL
ELSE 9999
END AS BMI_val,
'WLGP' AS source_db
FROM SAILW1483V.BMI_ALG_GP a
RIGHT JOIN
SAILW1483V.BMI_lookup b
ON a.event_cd = b.BMI_code AND b.category = 'obese'
WHERE
a.event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO
AND alf_sts_cd IN ('1', '4', '39')
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
;
--1e. Pulling ALL entries from WLGP that have BMI category allocated between the time-frame specified.
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_CAT');
CREATE TABLE SAILW1483V.BMI_CAT
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_cat VARCHAR(13),
BMI_c CHAR(1),
BMI_val DECIMAL(5),
source_db VARCHAR(12)
)
DISTRIBUTE BY HASH(ALF_PE);
COMMIT;
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_CAT with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_CAT activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_CAT
SELECT DISTINCT -- now we join all these tables together
*
FROM
SAILW1483V.UNDERWEIGHT
UNION ALL
SELECT DISTINCT
*
FROM
SAILW1483V.NORMALWEIGHT
UNION ALL
SELECT DISTINCT
*
FROM SAILW1483V.OVERWEIGHT
UNION ALL
SELECT DISTINCT
*
FROM SAILW1483V.OBESE
COMMIT;
-----------------------------------------------------------------------------------------------------------------
---2. Extracting BMI VALUES
-----------------------------------------------------------------------------------------------------------------
-- Here we extract ALL entries with BMI values from the time-frame specified.
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_VAL');
CREATE TABLE SAILW1483V.BMI_VAL
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_val DECIMAL(5),
BMI_cat CHAR(20),
BMI_c CHAR(1),
source_db VARCHAR(12)
)
DISTRIBUTE BY HASH(ALF_PE);
COMMIT;
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_VAL with distribution and detailed indexes all');
COMMIT;
INSERT INTO SAILW1483V.BMI_VAL
SELECT DISTINCT
ALF_PE,
BMI_dt,
BMI_val,
CASE
WHEN BMI_val < 18.5 THEN 'Underweight'
WHEN BMI_val >=18.5 AND BMI_val < 25 THEN 'Normal weight'
WHEN BMI_val >= 25.0 AND BMI_val < 30 THEN 'Overweight'
WHEN BMI_val >= 30.0 THEN 'Obese'
ELSE NULL
END AS BMI_cat, -- all the appropriate values will be assigned these categories.
CASE
WHEN BMI_val < 18.5 THEN '1'
WHEN BMI_val >=18.5 AND BMI_val < 25 THEN '2'
WHEN BMI_val >= 25.0 AND BMI_val < 30 THEN '3'
WHEN BMI_val >= 30.0 THEN '4'
ELSE NULL
END AS BMI_c, -- all the appropriate values will be assigned these numerical categories.
'WLGP' AS source_db
FROM
(
SELECT DISTINCT
ALF_PE,
event_dt AS BMI_dt,
event_val AS BMI_val
FROM
SAILW1483V.BMI_ALG_GP a -- all of the WLGP data which has event_cd
RIGHT JOIN
SAILW1483V.BMI_LOOKUP b -- that matches up the BMI_code in this table
ON a.event_cd = b.BMI_code
WHERE
category = 'BMI' -- all entries relating to 'BMI' which have:
AND alf_sts_cd IN ('1', '4', '39') -- all the acceptable sts_cd
AND event_val BETWEEN 12 AND 100 -- all the acceptable BMI values
AND event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO -- we want to capture the study date.
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
)
;
COMMIT;
-----------------------------------------------------------------------------------------------------------------
--3. extracting height and weight values from WLGP database.
-----------------------------------------------------------------------------------------------------------------
-- For each table, we want ALF_PE, height_dt/bmi_dt, height/weight, and source_db.
-- We only want valid readings, so not include NULL values.
-- We want to limit the extraction to our start and end dates.
--3.1.a. Extracting height from WLGP
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_HEIGHT_WLGP');
CREATE TABLE SAILW1483V.BMI_HEIGHT_WLGP
(
ALF_PE BIGINT,
height_dt DATE,
height DECIMAL(31,8),
source_db CHAR(4)
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_HEIGHT_WLGP with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_HEIGHT_WLGP activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_HEIGHT_WLGP
SELECT DISTINCT
ALF_PE,
event_dt AS height_dt,
event_val AS height,
'WLGP' AS source_db
FROM
SAILW1483V.BMI_ALG_GP a
RIGHT JOIN
SAILW1483V.BMI_LOOKUP b
ON a.event_cd = b.BMI_code AND b.category = 'height'
WHERE
(event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO)
AND alf_sts_cd IN ('1', '4', '39')
AND event_val IS NOT NULL
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT);
--3.1.b. Extracting weight from WLGP.
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_WEIGHT_WLGP');
CREATE TABLE SAILW1483V.BMI_WEIGHT_WLGP
(
ALF_PE BIGINT,
bmi_dt DATE,
weight INTEGER,
source_db CHAR(4)
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_WEIGHT_WLGP with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_WEIGHT_WLGP activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_WEIGHT_WLGP
SELECT DISTINCT
ALF_PE,
event_dt AS bmi_dt,
event_val AS weight,
'WLGP' AS source_db
FROM
SAILW1483V.BMI_ALG_GP a
RIGHT JOIN
SAILW1483V.BMI_LOOKUP b
ON a.event_cd = b.BMI_code AND b.category = 'weight'
WHERE
(event_dt BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO)
AND alf_sts_cd IN ('1', '4', '39')
AND event_val IS NOT NULL
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
;
COMMIT;
--3.4.a. Union all height tables
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_HEIGHT');
CREATE TABLE SAILW1483V.BMI_HEIGHT
(
ALF_PE BIGINT,
height_dt DATE,
height DECIMAL(31,8),
source_db CHAR(4)
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_HEIGHT with distribution and detailed indexes all');
COMMIT;
INSERT INTO SAILW1483V.BMI_HEIGHT -- creating a long table with all the height values from WLGP.
SELECT DISTINCT
*
FROM
SAILW1483V.BMI_HEIGHT_WLGP;
COMMIT;
--3.4.b. Union all weight tables
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_WEIGHT');
CREATE TABLE SAILW1483V.BMI_WEIGHT
(
ALF_PE BIGINT,
bmi_dt DATE,
weight INTEGER,
source_db CHAR(4)
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_WEIGHT with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_WEIGHT activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_WEIGHT --creating a long table with all the weight values from WLGP.
SELECT DISTINCT
*
FROM
SAILW1483V.BMI_WEIGHT_WLGP;
COMMIT;
-----------------------------------------------------------------------------------------------------------------
---4. extracting ALF_PEs WITH code FROM PEDW
-----------------------------------------------------------------------------------------------------------------
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_PEDW');
CREATE TABLE SAILW1483V.BMI_PEDW
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_cat VARCHAR(13),
BMI_c CHAR(1),
source_db CHAR(4)
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_PEDW with distribution and detailed indexes all');
COMMIT;
INSERT INTO SAILW1483V.BMI_PEDW
SELECT distinct ALF_PE,
ADMIS_DT AS BMI_dt,
'Obese' AS BMI_cat,
'4' AS BMI_c,
'PEDW' AS source_db
FROM
SAILW1483V.BMI_ALG_PEDW_SPELL a
INNER JOIN
SAILW1483V.BMI_ALG_PEDW_DIAG b
USING
(SPELL_NUM_PE)
WHERE
(ADMIS_DT BETWEEN SAILW1483V.BMI_DATE_FROM AND SAILW1483V.BMI_DATE_TO)
AND DIAG_CD LIKE 'E66%' -- ICD-10 codes that match this have obesity diagnoses.
AND alf_sts_cd IN ('1', '4', '39')
AND ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT);
COMMIT;
--------------------------------------------------------------
------------ Putting all BMI data in one table.
--------------------------------------------------------------
-- 5.1 Here we put all the BMI data in one table. We allocate a hierarchical rank based on source type.
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_COMBO_STAGE_1');
CREATE TABLE SAILW1483V.BMI_COMBO_STAGE_1
(
ALF_PE BIGINT,
BMI_dt DATE,
BMI_cat VARCHAR(13),
BMI_c CHAR(1),
BMI_val DECIMAL(5),
height DECIMAL(31,8),
weight INTEGER,
source_type VARCHAR(50),
source_rank SMALLINT,
source_db CHAR(4)
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_COMBO_STAGE_1 with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_COMBO_STAGE_1 activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_COMBO_STAGE_1
SELECT DISTINCT -- removes duplicates
*
FROM
(
SELECT
ALF_PE,
BMI_dt,
BMI_cat,
BMI_c,
BMI_val,
NULL AS height,
NULL AS weight,
'BMI category' AS source_type,
'5' AS source_rank,
source_db
FROM
SAILW1483V.BMI_CAT
UNION ALL
SELECT
ALF_PE,
BMI_dt,
BMI_cat,
BMI_c,
BMI_val,
NULL AS height,
NULL AS weight,
'BMI value' AS source_type,
'1' AS source_rank,
source_db
FROM
SAILW1483V.BMI_VAL
UNION ALL
SELECT
ALF_PE,
height_dt AS BMI_dt,
NULL AS BMI_cat,
NULL AS BMI_c,
NULL AS BMI_val,
height,
NULL AS weight,
'height' AS source_type,
'2' AS source_rank,
source_db
FROM SAILW1483V.BMI_HEIGHT
WHERE
source_db = 'WLGP'
UNION ALL
SELECT
ALF_PE,
bmi_dt AS BMI_dt,
NULL AS BMI_cat,
NULL AS BMI_c,
NULL AS BMI_val,
NULL AS height,
weight,
'weight' AS source_type,
'2' AS source_rank,
source_db
FROM SAILW1483V.BMI_WEIGHT
WHERE
source_db = 'WLGP'
UNION ALL
SELECT
ALF_PE,
BMI_dt,
BMI_cat,
BMI_c,
NULL AS BMI_val,
NULL AS height,
NULL AS weight,
'ICD-10' AS source_type,
'6' AS source_rank,
source_db
FROM
SAILW1483V.BMI_PEDW
)
;
---------------------------------------------
-- Stage 2. Linking WDSD tables.
--------------------------------------------
-- we only want to select ALFs with valid WOB, valid gndr_cd, and those who were alive after the start date.
-- we also calculate how many days each ALF has contributed to the data so we created a follow_up_dod (when they died) and follow_up_res (when they moved out of Wales)
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_COMBO_STAGE_2');
CREATE TABLE SAILW1483V.BMI_COMBO_STAGE_2
(
ALF_PE BIGINT,
sex CHAR(1),
wob DATE,
bmi_dt DATE,
bmi_cat VARCHAR(13),
bmi_c CHAR(1),
bmi_val DECIMAL(5),
height DECIMAL(31,8),
weight INTEGER,
source_type VARCHAR(50),
source_rank SMALLINT,
source_db CHAR(4),
active_from DATE,
active_to DATE,
dod DATE,
follow_up_dod INTEGER,
follow_up_res INTEGER
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_COMBO_STAGE_2 with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_COMBO_STAGE_2 activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_COMBO_STAGE_2 -- attaching dod, from_dt, to_dt to BMI_COMBO and creating the follow_up field.
SELECT
*,
-- counting how many days they contributed to the data before death
-- this creates a flag which counts the difference between study start date and DOD.
-- we will remove those with > 31 days follow up in the next stage.
abs(DAYS_BETWEEN(dod, SAILW1483V.BMI_DATE_FROM)) AS follow_up_dod,
-- counting how many days they contributed to the data before moving out
abs(DAYS_BETWEEN(active_from, SAILW1483V.BMI_DATE_TO)) AS follow_up_res
FROM
(
SELECT DISTINCT
a.ALF_PE,
b.sex,
b.wob,
bmi_dt,
bmi_cat,
bmi_c,
bmi_val,
height,
weight,
source_type,
source_rank,
source_db,
b.active_from_2 AS active_from,
b.active_to_2 AS active_to,
CASE
WHEN b.dod IS NOT NULL THEN b.DOD
ELSE '9999-01-01'
END AS dod
FROM
SAILW1483V.BMI_COMBO_STAGE_1 a
LEFT JOIN
(
SELECT DISTINCT
*,
CASE -- if they lived in Wales before the study start date, this is changed to the study start date for the calculation of follow_up_res
WHEN active_from < SAILW1483V.BMI_DATE_FROM THEN SAILW1483V.BMI_DATE_FROM
ELSE active_from
END AS active_from_2,
CASE -- if they are still living in Wales at present, change to end of study date.
WHEN active_to IS NULL THEN SAILW1483V.BMI_DATE_TO
ELSE active_to
END AS active_to_2
FROM
(
SELECT
ALF_PE,
gndr_cd AS sex,
wob,
death_dt AS dod,
CAST(activefrom AS date) AS active_from,
CAST(activeto AS date) AS active_to
FROM
SAILW1483V.BMI_ALG_WDSD -- the single view wdsd table.
WHERE ALF_PE IN (SELECT ALF_PE FROM SAILW1483V.PREP_DIABETES_INC_PREV_FIRST_SPLIT)
)
) b
ON a.ALF_PE = b.ALF_PE AND a.bmi_dt BETWEEN b.active_from AND b.active_to_2
WHERE
b.wob IS NOT NULL -- we only want to keep ALFs that have WOB
AND (b.sex IN ('1', '2') AND b.sex IS NOT NULL) -- we want ALFs with valid gndr_cd
OR b.dod > SAILW1483V.BMI_DATE_FROM -- we want ALFs who were alive after the start date.
-- we want ALFs who were alive after the start date. NOTE if I use 'AND', this returns 0 entries. 'OR' function works.
);
------- selecting only those with 31 days follow up
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_COMBO');
-- this creates the general combo table.
CREATE TABLE SAILW1483V.BMI_COMBO
(
ALF_PE BIGINT,
sex CHAR(1),
wob DATE,
bmi_dt DATE,
bmi_cat VARCHAR(13),
bmi_c CHAR(1),
bmi_val DECIMAL(5),
height DECIMAL(31,8),
weight INTEGER,
source_type VARCHAR(50),
source_rank SMALLINT,
source_db CHAR(4),
active_from DATE,
active_to DATE,
dod DATE,
follow_up_dod INTEGER,
follow_up_res INTEGER
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_COMBO with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_COMBO activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_COMBO
SELECT
ALF_PE,
sex,
wob,
bmi_dt,
bmi_cat,
bmi_c,
bmi_val,
height,
weight,
source_type,
source_rank,
source_db,
CASE
WHEN active_from IS NULL THEN SAILW1483V.BMI_DATE_FROM
WHEN active_from IS NOT NULL THEN active_from
END AS active_from,
CASE
WHEN active_to IS NOT NULL THEN active_to
WHEN active_to IS NULL THEN SAILW1483V.BMI_DATE_TO
END AS active_to,
dod,
follow_up_dod,
follow_up_res
FROM
SAILW1483V.BMI_COMBO_STAGE_2
WHERE
follow_up_dod > 31; -- we only want ALFs who were alive/in the study after 31 days of the study start date.
COMMIT;
-------------------------------------------------------------------------------
---- Stage 3. Calculating age and pairing height and weight for ADULT COHORT
-------------------------------------------------------------------------------
CALL FNC.DROP_IF_EXISTS ('SAILW1483V.BMI_COMBO_ADULTS_STAGE_1');
CREATE TABLE SAILW1483V.BMI_COMBO_ADULTS_STAGE_1
(
ALF_PE BIGINT,
sex CHAR(1),
wob DATE,
bmi_dt DATE,
bmi_cat VARCHAR(13),
bmi_c CHAR(1),
bmi_val DECIMAL(5),
height DECIMAL(31,8),
weight INTEGER,
source_type VARCHAR(50),
source_rank SMALLINT,
source_db CHAR(4),
active_from DATE,
active_to DATE,
dod DATE,
follow_up_dod INTEGER,
follow_up_res INTEGER
)
DISTRIBUTE BY HASH(ALF_PE);
CALL SYSPROC.ADMIN_CMD('runstats on table SAILW1483V.BMI_COMBO_ADULTS_STAGE_1 with distribution and detailed indexes all');
COMMIT;
ALTER TABLE SAILW1483V.BMI_COMBO_ADULTS_STAGE_1 activate not logged INITIALLY;
INSERT INTO SAILW1483V.BMI_COMBO_ADULTS_STAGE_1
WITH height_table AS
-- creating the height table
-- 1.standardising measurements
-- 2. taking only height that is recorded in adulthood
-- 3. taking only the most recent height for adults.
(
SELECT
ALF_PE,
sex,
wob,
bmi_dt,
bmi_cat,
bmi_c,
bmi_val,
height_standard AS height,
source_type,
source_rank,
source_db,
active_from,
active_to,
dod,
follow_up_dod,
follow_up_res
FROM
(
SELECT
*,
CASE
WHEN height BETWEEN 1.2 AND 2.13 THEN height
WHEN height BETWEEN 120 AND 213 THEN height/100 -- converts centimeters to meters
WHEN height BETWEEN 48 AND 84 THEN (height*2.54)/100 -- converts inches to meters
ELSE NULL
END AS height_standard,
ROW_NUMBER() OVER (PARTITION BY ALF_PE ORDER BY bmi_dt desc) AS event_order, -- to get the most recent height reading
DAYS_BETWEEN (bmi_dt, wob)/365.25 AS age_height
FROM
SAILW1483V.BMI_COMBO
WHERE
source_type = 'height' -- selecting entries that are only height values
AND height != 0 -- it will not calculate if 0 is used as denominator.
)
WHERE
event_order = 1 -- select only the latest reading for adults
AND age_height BETWEEN 19 AND 100 -- only height readings done when they were adults are kept to be used to calculate BMI.
),
weight_table AS-- weight TABLE
-- extracting weight measurements from BMI_COMBO table.
(
SELECT
ALF_PE,
sex,
wob,
bmi_dt,
bmi_cat,
bmi_c,
bmi_val,
weight,
source_type,
source_rank,
source_db,
active_from,
active_to,
dod,
follow_up_dod,
follow_up_res
FROM
SAILW1483V.BMI_COMBO
WHERE
source_type = 'weight'
AND DAYS_BETWEEN (bmi_dt, wob)/365.25 BETWEEN 19 AND 100 -- want to include ALFs who were aged 19 and 100 at the time of BMI reading.
),
height_weight AS
-- calculating BMI value from the latest height reading for each ALF and the weight entries.
(
SELECT
ALF_PE,
sex,
wob,
bmi_dt,
CASE
WHEN bmi_val < 18.5 THEN 'Underweight'
WHEN bmi_val >=18.5 AND bmi_val < 25 THEN 'Normal weight'
WHEN bmi_val >= 25.0 AND bmi_val < 30 THEN 'Overweight'
WHEN bmi_val >= 30.0 THEN 'Obese'
ELSE NULL
END AS bmi_cat, -- all the appropriate values will be assigned these categories.
CASE
WHEN bmi_val < 18.5 THEN '1'
WHEN bmi_val >=18.5 AND bmi_val < 25 THEN '2'
WHEN bmi_val >= 25.0 AND bmi_val < 30 THEN '3'
WHEN bmi_val >= 30.0 THEN '4'
ELSE NULL
END AS bmi_c,
bmi_val,
height,
weight,