HANDLING MISSING VALUES/NULLS

In the world of data, deciding how to handle missing values is a common task. Is the absence of a value meaningful or meaningless? Will the absence of a value negatively affect our ability to make an accurate calculation resulting in a value that isn’t misleading? Do the consumers of our dashboards and/or reports understand the concept of NULL and if they do, is it desirable to populate a value instead of showing nothing or NULL? These are only a handful of the possible questions you may need to answer regarding NULLs or missing values. Let’s quickly look at a widely available function across relational database management system products and then dive into a few examples.

Step forward, COALESCE. The COALESCE function accepts two or more arguments and returns the first non-null argument. Easy right? Now for the examples. The schemas, corresponding tables, and data used in the examples can be found at livesql.oracle.com.

At times, it may be ideal to populate NULLs or missing values with a value that provides meaning to the consumers of your data. In the following two examples, missing values are populated with the value 999. In the first example, the value is populated with 999 to indicate the employee isn’t managed by another employee. In the second example, orders without an associated sales representative are populated with the value 999.

-- Replace missing manager ID values with 999.
SELECT
    hr.employees.employee_id,
    COALESCE(hr.employees.manager_id, 999) AS manager_id
FROM
    hr.employees;
employee_idmanager_id
100999
101100
102100
-- Replace missing sales representative ID values with 999.
SELECT
    COALESCE(oe.orders.sales_rep_id, 999) AS sales_rep_id,
    CASE
        WHEN oe.orders.sales_rep_id IS NULL
            THEN 'Online'
        ELSE 'In-store'
    END AS order_type,
    SUM(oe.orders.order_total) AS order_total
FROM
    oe.orders
GROUP BY
    sales_rep_id,
    CASE
        WHEN oe.orders.sales_rep_id IS NULL
            THEN 'Online'
        ELSE 'In-store'
    END
ORDER BY
    sales_rep_id DESC;
sales_rep_idorder_typeorder_total
999Online1859147.3
163In-store128249.5
161In-store661734.5
160In-store88238.4
159In-store151167.2
158In-store156296.2
156In-store202617.6
155In-store134415.2
154In-store171973.1
153In-store114215.7

The two examples above are relatively straightforward. The scenario and use of COALESCE simply replaced the missing values with a hard-coded default value. In the next example, product price values will be imputed based on the average price of those products in the same category. The strategy below allows us to step away from hard-coding missing values. Instead, the missing values will reflect the average price at run-time.

-- Solution utilizing a CTE and a correlated subquery in the SELECT clause.
WITH impute AS (
    SELECT
    	product.category_id,
    	AVG(product.list_price) AS average_price
    FROM
    	oe.product_information product
    GROUP BY
    	product.category_id
)
SELECT
    product.product_id,
    product.category_id,
    COALESCE(product.list_price,
        (
            SELECT
                impute.average_price
            FROM
                impute
            WHERE
                impute.category_id = product.category_id
        )
    ) AS list_price
FROM
    oe.product_information product;

-- Solution utilizing a CTE and an INNER join.
WITH impute AS (
    SELECT
    	product.category_id,
    	AVG(product.list_price) AS average_price
    FROM
    	oe.product_information product
    GROUP BY
    	product.category_id
)
SELECT
    product.product_id,
    product.category_id,
    COALESCE(product.list_price, impute.average_price) AS list_price
FROM
    oe.product_information product
    INNER JOIN
    impute
        ON product.category_id = impute.category_id;
product_idcategory_idlist_price
179712349
245912699
312712498
225413453
335313489
306913436
225313399
335413543
307213567
333413612
307113633
225513775
174313800
238213850
339913815
307313224
176813345
241013357
225713399
340013389
335513517.75
177213456
224311350
305711369
306111499
224511512
306511999
333111879
225211889
3064111023
31551149
32341139
335011740
223611964
305411600
178212125
243012175
179212225
179112275
230212150
245312195
2810326
2870325
178117233
226417223
22601767
226617333
307717274
22591739
22611742
30821781
22701766
22681777
30831767
23741765
174017134
240917210
22621798
25221944
22781955
24181961
24191972
3097193
3099194
2380196
2408194
2457195
2373196
1734196
1737198
1745199
29821944
32771936
29761952
320419126
263819137
302019449
194819498
3003193219
299919999
3000191749
3001192556
3004192768
33911985
31241984
17381986
23771997
22991976
241413454
241513359
239514123
175514121
240614223
240414221
177014250.78
24121498
237814305
308714124
238414599
174914337
175014699
239414128
240014448
176314247
239614179
227214135
227414161
309014193
173914299
335914111
308814258
227614269
308614211
309114279
178715101
243915123
178815178
23751578
24111598
17691548
20491555
27511566
31121577
27521588
22931599
311415101
31291546
31331548
23081558
249615299
249715399
31061648
22891648
31101648
31081678
20581623
27611627
31171641
2056168
2211164
2944163
174217101
240217127
240317117
176117134
23811799
242417221
172611259
235911249
306011299
30513212
31503218
3208322
32093213
32243232
32253247
3511329
3515322
298633125
31633335
31653340
31673355
32163330
32203345
17293980
19103914
19123915
19403918
20303912
2326392
2330392
2334394
23403972
23653978
2594399
25963912
26313915
27213987
272239112
2725394
27823962
3187393
3189392
3191392
3193393
31231981
17481983
23871983
23701991
23111995
17331989
287819345
287919456
215219231
33011915
31431916
23231918
31341918
31391921
33001923
23161922
31401924
23191925
23221923
31782145
31792150
31822265
31832250
31972145
32552135
32562140
32602250
32622150
33612140
1799241000
180124100
18032460
18042465
18052450
18062450
18082455
18202455
1822241500
242224150
245224100
24622480
24642470
24672480
24682475
24702480
247124500
24922445
24932425
24942425
29952470
32902465
17782562
177925128
178025450
237125146
24232584
350125555
350225105
35032522
177429110
17752927
179429128
18252925
20042990
200529115
24162941
24172933
24492983
31012975
317029161
317129148
31722942
31732986
31752937
317629120
317729120
324529222
324629222
324729120
324829222
32502928
32512931
32522926
325329222
32572966
32582980
33622999
2231312510
233531100
2350312500
2351312900
2779313980
333731800
2091321
2093328
21443218
23363255
233732300
23393225
25363280
253732200
27833210
2808321