-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinventory.sql
More file actions
692 lines (609 loc) · 23.5 KB
/
Copy pathinventory.sql
File metadata and controls
692 lines (609 loc) · 23.5 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
--#############################################################################################
--#################################### EMPLOYEE DATA ##########################################
--#############################################################################################
--=============================================================================================
--=========================== inventory_snapshots table overview ==============================
--=============================================================================================
SELECT TOP (1000)
[snapshot_date]
,[product_id]
,[product_name]
,[sku]
,[category]
,[stock_on_hand]
,[stock_reserved]
,[stock_available]
,[reorder_level]
,[unit_cost]
,[unit_price]
,[inventory_value]
,[warehouse_location]
,[store_id]
FROM [bronze].[inventory_snapshots]
--=============================================================================================
--============================== snapshot_date column cleaning ================================
--=============================================================================================
-- snapshot_date overview
SELECT
snapshot_date
FROM bronze.inventory_snapshots ;
-- snapshot_date pattern analysis
WITH date_pattern_analysis AS
(
SELECT
TRANSLATE(
TRIM(LOWER(snapshot_date)),
'0123456789abcdefghijklmnopqrstuvwxyz',
'9999999999aaaaaaaaaaaaaaaaaaaaaaaaaa'
) AS date_pattern
FROM bronze.inventory_snapshots
)
SELECT
date_pattern,
COUNT(*) AS pattern_count,
CAST(
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER(), 2) AS NVARCHAR
) + '%' AS percentage
FROM date_pattern_analysis
GROUP BY date_pattern
ORDER BY pattern_count DESC ;
-- MM/DD/YYYY format analysis
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '__/__/____' ;
-- MM/DD/YYYY month validation check
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '__/__/____'
AND SUBSTRING(snapshot_date, 4, 2) > 12;
-- DD/MM/YYYY day validation check
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '__/__/____'
AND LEFT(snapshot_date, 2) > 12;
-- Mon DD, YYYY format analysis
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '[A-Z][a-z][a-z] __, ____' ; -- DONE
-- YYYY/MM/DD format analysis
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '____/__/__' ; -- DONE
-- MM-DD-YYYY format analysis
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '__-__-____' ;
-- MM-DD-YYYY month validation check
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '__-__-____'
AND SUBSTRING(snapshot_date, 4, 2) > 12;
-- DD-MM-YYYY day validation check
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '__-__-____'
AND LEFT(snapshot_date, 2) > 12;
-- YYYY-MM-DD format analysis
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '____-__-__' ; -- DONE
-- Month DD, YYYY format analysis
SELECT
snapshot_date
FROM bronze.inventory_snapshots
WHERE snapshot_date LIKE '[A-Z][a-z][a-z][a-z] __, ____' ; -- DONE
-- Final snapshot_date cleaning validation
WITH snapshot_date_analysis AS
(
SELECT
CASE
WHEN snapshot_date LIKE '[A-Z][a-z][a-z][a-z] __, ____' THEN TRY_CONVERT(DATE, snapshot_date)
WHEN snapshot_date LIKE '[A-Z][a-z][a-z] __, ____' THEN TRY_CONVERT(DATE, snapshot_date)
WHEN snapshot_date LIKE '____/__/__' THEN TRY_CONVERT(DATE, snapshot_date)
WHEN snapshot_date LIKE '____-__-__' THEN TRY_CONVERT(DATE, snapshot_date)
WHEN snapshot_date LIKE '__/__/____' AND SUBSTRING(snapshot_date, 4, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 101)
WHEN snapshot_date LIKE '__/__/____' AND LEFT(snapshot_date, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 103)
WHEN snapshot_date LIKE '__-__-____' AND SUBSTRING(snapshot_date, 4, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 110)
WHEN snapshot_date LIKE '__-__-____' AND LEFT(snapshot_date, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 105)
ELSE TRY_CONVERT(DATE, snapshot_date)
END AS snapshot_date
FROM bronze.inventory_snapshots
)
SELECT
snapshot_date
FROM snapshot_date_analysis
WHERE snapshot_date IS NULL ;
--=============================================================================================
--================================= product_id column cleaning ================================
--=============================================================================================
-- product_id data profiling
SELECT
product_id
FROM bronze.inventory_snapshots
WHERE product_id IS NULL
OR product_id = ''
OR TRY_CONVERT(INT, product_id) IS NULL ;
-- product_id distribution analysis
SELECT
product_id,
COUNT(*) product_id_count,
CAST(ROUND(COUNT(*)*100.0/SUM(COUNT(*)) OVER(), 2) AS NVARCHAR) + '%' as percentages
FROM bronze.inventory_snapshots
GROUP BY product_id
ORDER BY product_id_count ;
-- Final product_id cleaning validation
SELECT
CASE
WHEN TRY_CONVERT(INT, product_id) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, product_id)
END as product_id
FROM bronze.inventory_snapshots ;
--=============================================================================================
--================================= product_name column cleaning ==============================
--=============================================================================================
-- producnt_name data profiling
SELECT
product_name
FROM bronze.inventory_snapshots
WHERE product_name IS NULL
OR product_name = ''
OR product_name != TRIM(product_name)
OR LEN(product_name) < 4 ;
-- product_name distribution analysis
SELECT
product_name,
COUNT(*) product_name_count,
CAST(ROUND(COUNT(*)*100.0/SUM(COUNT(*)) OVER(), 2) AS NVARCHAR) + '%' as percentages
FROM bronze.inventory_snapshots
GROUP BY product_name
ORDER BY product_name_count ;
-- Final Product_name cleaning validation
SELECT
CASE
WHEN product_name IS NULL OR product_name = '' THEN 'Unknown'
ELSE TRIM(product_name)
END as product_name
FROM bronze.inventory_snapshots
--=============================================================================================
--==================================== sku column cleaning ====================================
--=============================================================================================
-- sku data profiling
SELECT
sku
FROM bronze.inventory_snapshots
WHERE sku IS NULL
OR sku = ''
OR sku != TRIM(product_name)
OR LEN(sku) < 4 ;
-- product_name distribution analysis
SELECT
sku,
COUNT(*) sku_count,
CAST(ROUND(COUNT(*)*100.0/SUM(COUNT(*)) OVER(), 2) AS NVARCHAR) + '%' as percentages
FROM bronze.inventory_snapshots
GROUP BY sku
ORDER BY sku_count ;
-- Final sku cleaning validation
SELECT
CASE
WHEN sku IS NULL OR sku = '' THEN 'Unknown'
ELSE TRIM(sku)
END as sku
FROM bronze.inventory_snapshots ;
--=============================================================================================
--=============================== category column cleaning ====================================
--=============================================================================================
-- category data profiling
SELECT
category
FROM bronze.inventory_snapshots
WHERE category IS NULL
OR category = ''
OR category != TRIM(category) ;
SELECT DISTINCT
category
FROM bronze.inventory_snapshots
-- category distribution analysis
SELECT
category,
COUNT(*) category_count,
CAST(ROUND(COUNT(*)*100.0/SUM(COUNT(*)) OVER(), 2) AS NVARCHAR) + '%' as percentages
FROM bronze.inventory_snapshots
GROUP BY category
HAVING COUNT(*) > 1
ORDER BY category_count DESC;
-- category case-sensitive distribution analysis
SELECT
category COLLATE Latin1_General_CS_AS as category ,
COUNT(*) as total_count
FROM bronze.inventory_snapshots
GROUP BY category COLLATE Latin1_General_CS_AS
ORDER BY total_count DESC ;
-- category cleaning and standardization
WITH category_analysis AS
(
SELECT
CASE
WHEN TRIM(LOWER(category)) = 'electronics' THEN 'Electronics'
WHEN TRIM(LOWER(category)) = 'clothing' THEN 'Clothing'
WHEN TRIM(LOWER(category)) = 'kitchen' THEN 'Kitchen'
WHEN TRIM(LOWER(category)) = 'office' THEN 'Office'
WHEN TRIM(LOWER(category)) = 'sports' THEN 'Sports'
WHEN TRIM(LOWER(category)) = 'health' THEN 'Health'
WHEN TRIM(LOWER(category)) = 'beauty' THEN 'Beauty'
WHEN TRIM(LOWER(category)) = 'footwear' THEN 'Footwear'
WHEN TRIM(LOWER(category)) = 'toys' THEN 'Toys'
WHEN TRIM(LOWER(category)) = 'bags' THEN 'Bags'
ELSE 'Unknown'
END AS category
FROM bronze.inventory_snapshots
)
SELECT
category COLLATE Latin1_General_CS_AS as category ,
COUNT(*) as total_count
FROM category_analysis
GROUP BY category COLLATE Latin1_General_CS_AS
ORDER BY total_count DESC ;
--=============================================================================================
--=============================== stock_on_hand column cleaning ===============================
--=============================================================================================
-- stock_on_hand data overview
SELECT
stock_on_hand
FROM bronze.inventory_snapshots ;
--stock_on_hand data profiling
SELECT
stock_on_hand
FROM bronze.inventory_snapshots
WHERE stock_on_hand IS NULL
OR stock_on_hand < 0
OR TRY_CONVERT(INT, stock_on_hand) IS NULL ;
--Stock_on_hand cleaning and standardization
SELECT
CASE
WHEN TRY_CONVERT(INT, stock_on_hand) IS NULL OR stock_on_hand < 0 THEN NULL
ELSE TRY_CONVERT(INT, stock_on_hand)
END AS stock_on_hand
FROM bronze.inventory_snapshots
WHERE stock_on_hand IS NULL ;
--=============================================================================================
--=============================== stock_reserved column cleaning ==============================
--=============================================================================================
-- stock_reserved data overview
SELECT
stock_reserved
FROM bronze.inventory_snapshots ;
-- stock_reserved data profiling
SELECT
stock_reserved
FROM bronze.inventory_snapshots
WHERE stock_reserved IS NULL
OR stock_reserved < 0
OR TRY_CONVERT(INT, stock_reserved) IS NULL ;
-- stock_reserved cleaning and standardization
SELECT
CASE
WHEN stock_reserved < 0 OR TRY_CONVERT(INT, stock_reserved) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, stock_reserved)
END as stock_reserved
FROM bronze.inventory_snapshots
WHERE stock_reserved IS NULL ;
--=============================================================================================
--============================= stock_available column cleaning ===============================
--=============================================================================================
-- stock_available data overview
SELECT
stock_available
FROM bronze.inventory_snapshots
-- stock_available data profilint
SELECT
stock_available
FROM bronze.inventory_snapshots
WHERE stock_available IS NULL
OR stock_available < 0
OR TRY_CONVERT(INT, stock_available) IS NULL ;
-- null count in stock_available
SELECT
COUNT(*) as null_count
FROM bronze.inventory_snapshots
WHERE stock_available IS NULL ;
-- not null count in stock_available
SELECT
stock_available
FROM bronze.inventory_snapshots
WHERE stock_available IS NOT NULL ;
-- stock_available cleaning and standardization
SELECT
CASE
WHEN stock_available IS NULL THEN stock_on_hand - stock_reserved
WHEN TRY_CONVERT(INT, stock_available) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, stock_available)
END as stock_available
FROM bronze.inventory_snapshots ;
--=============================================================================================
--=============================== reorder_level column cleaning ===============================
--=============================================================================================
-- reorder_level data overview
SELECT
reorder_level
FROM bronze.inventory_snapshots ;
--reorder_level data profiling
SELECT
reorder_level
FROM bronze.inventory_snapshots
WHERE reorder_level IS NULL
OR reorder_level < 0
OR TRY_CONVERT(INT, reorder_level) IS NULL ;
-- reorder_level cleaning and standardization
SELECT
CASE
WHEN reorder_level IS NULL OR reorder_level < 0 OR TRY_CONVERT(INT, reorder_level) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, reorder_level)
END as reorder_level
FROM bronze.inventory_snapshots ;
--=============================================================================================
--=============================== unit_cost column cleaning ===================================
--=============================================================================================
-- unite_cost data overview
SELECT
unit_cost
FROM bronze.inventory_snapshots ;
-- unite_cost data profiling
SELECT
unit_cost
FROM bronze.inventory_snapshots
WHERE unit_cost IS NULL
OR TRY_CONVERT(DECIMAL(10, 2), unit_cost) IS NULL ;
-- unit_cost cleaning and standardization
SELECT
CASE
WHEN unit_cost LIKE '$%' THEN SUBSTRING(unit_cost, 2, LEN(unit_cost))
ELSE TRY_CONVERT(DECIMAL(10, 2), unit_cost)
END as unit_cost
FROM bronze.inventory_snapshots ;
--=============================================================================================
--================================== unit_price column cleaning ===============================
--=============================================================================================
-- unit_price data overview
SELECT
unit_price
FROM bronze.inventory_snapshots ;
-- selecting those unite price they contani '$' symbol
SELECT
unit_price
FROM bronze.inventory_snapshots
WHERE unit_price LIKE '$%' ;
-- selecting those unite price they contani ',' symbol
SELECT
unit_price
FROM bronze.inventory_snapshots
WHERE unit_price LIKE '%,%' ;
-- finding those unit price they are 0
SELECT
unit_price
FROM bronze.inventory_snapshots
WHERE TRY_CONVERT(DECIMAL(10,2), REPLACE(REPLACE(unit_price, '$', ''), ',', '')) < 1 ;
-- unit_price data profiling
SELECT
unit_price
FROM bronze.inventory_snapshots
WHERE unit_price IS NULL
OR TRY_CONVERT(DECIMAL(10, 2), unit_price) IS NULL
OR unit_price LIKE '$%'
OR unit_price LIKE '%,%' ;
-- unit_price data profiling
SELECT
unit_price
FROM bronze.inventory_snapshots
WHERE unit_price IS NULL
OR TRY_CONVERT(DECIMAL(10, 2), REPLACE(REPLACE(unit_price, ',', ''), '$', '')) IS NULL ;
-- unit_price cleaning and standardization
WITH unit_price_analysis AS
(
SELECT
CASE
WHEN TRY_CONVERT(DECIMAL(10,2), unit_price) IS NULL THEN TRY_CONVERT(DECIMAL(10,2), REPLACE(REPLACE(unit_price, ',', ''), '$', ''))
ELSE TRY_CONVERT(DECIMAL(10, 2), unit_price)
END as unit_price
FROM bronze.inventory_snapshots
)
SELECT
unit_price
FROM unit_price_analysis
WHERE unit_price IS NULL ;
--=============================================================================================
--=============================== inventory_value column cleaning ============================
--=============================================================================================
-- inventory_value data overview
SELECT
inventory_value
FROM bronze.inventory_snapshots ;
-- inventory_value data profiling
SELECT
inventory_value
FROM bronze.inventory_snapshots
WHERE inventory_value IS NULL ;
-- inventory_value null count
SELECT
inventory_value
FROM bronze.inventory_snapshots
WHERE inventory_value IS NOT NULL ;
-- data prifiling and standardization
WITH calc_inventory_value AS
(
SELECT
CASE
WHEN TRY_CONVERT(INT, stock_on_hand) IS NULL OR stock_on_hand < 0 THEN NULL
ELSE TRY_CONVERT(INT, stock_on_hand)
END AS stock_on_hand
,CASE
WHEN TRY_CONVERT(DECIMAL(10,2), unit_price) IS NULL THEN TRY_CONVERT(DECIMAL(10,2), REPLACE(REPLACE(unit_price, ',', ''), '$', ''))
ELSE TRY_CONVERT(DECIMAL(10, 2), unit_price)
END as unit_price
FROM bronze.inventory_snapshots
)
SELECT
COUNT(*) AS total_rows,
COUNT(stock_on_hand) AS valid_stock,
COUNT(unit_price) AS valid_price
FROM calc_inventory_value;
-- unit_price cleaning and standardization
WITH calc_inventory_value AS
(
SELECT
CASE
WHEN TRY_CONVERT(INT, stock_on_hand) IS NULL OR stock_on_hand < 0 THEN NULL
ELSE TRY_CONVERT(INT, stock_on_hand)
END AS stock_on_hand
,CASE
WHEN TRY_CONVERT(DECIMAL(10,2), unit_price) IS NULL THEN TRY_CONVERT(DECIMAL(10,2), REPLACE(REPLACE(unit_price, ',', ''), '$', ''))
ELSE TRY_CONVERT(DECIMAL(10, 2), unit_price)
END as unit_price
FROM bronze.inventory_snapshots
)
SELECT
stock_on_hand * unit_price as inventory_value
FROM calc_inventory_value ;
--=============================================================================================
--=============================== warehouse_location column cleaning =========================
--=============================================================================================
-- warehouse_location data overview
SELECT
warehouse_location
FROM bronze.inventory_snapshots ;
-- warehouse_location unique data overview
SELECT DISTINCT
warehouse_location
FROM bronze.inventory_snapshots ;
-- warehouse_location case-sensitive data profiling
SELECT DISTINCT
UPPER(warehouse_location) COLLATE Latin1_General_CS_AS as warehouse_location
FROM bronze.inventory_snapshots ;
-- warehouse_location data profiling and standardization
SELECT
CASE
WHEN warehouse_location IS NULL OR warehouse_location = '' THEN 'Unknown'
ELSE UPPER(warehouse_location)
END as warehouse_location
FROM bronze.inventory_snapshots ;
--=============================================================================================
--================================= store_id column cleaning =================================
--=============================================================================================
-- store_id data overview
SELECT
store_id
FROM bronze.inventory_snapshots ;
-- store_id data profiling
SELECT
store_id
FROM bronze.inventory_snapshots
WHERE store_id IS NULL OR store_id = ''
OR TRY_CONVERT(INT, store_id) IS NULL ;
-- store id distribution analysis
SELECT
store_id,
COUNT(*) store_id_count,
CAST(ROUND(COUNT(*)*100.0/SUM(COUNT(*)) OVER(), 2) AS NVARCHAR) + '%' as percentages
FROM bronze.inventory_snapshots
GROUP BY store_id
ORDER BY store_id_count DESC ;
-- store_id cleaning and standardization
SELECT
CASE
WHEN store_id IS NULL OR store_id = '' THEN NULL
ELSE TRY_CONVERT(INT, store_id)
END as store_id
FROM bronze.inventory_snapshots ;
--#############################################################################################
--############################## EMPLOYEE CLEAN DATA ##########################################
--#############################################################################################
SELECT
snapshot_date
,product_id
,product_name
,sku
,category
,stock_on_hand
,stock_reserved
,stock_on_hand - stock_reserved as stock_available
,reorder_level
,unit_cost
,unit_price
,unit_price * stock_on_hand as inventory_value
,warehouse_location
,store_id
FROM
(
SELECT
CASE
WHEN snapshot_date LIKE '[A-Z][a-z][a-z][a-z] __, ____' THEN TRY_CONVERT(DATE ,snapshot_date)
WHEN snapshot_date LIKE '[A-Z][a-z][a-z] __, ____' THEN TRY_CONVERT(DATE ,snapshot_date)
WHEN snapshot_date LIKE '____/__/__' THEN TRY_CONVERT(DATE ,snapshot_date)
WHEN snapshot_date LIKE '____-__-__' THEN TRY_CONVERT(DATE ,snapshot_date)
WHEN snapshot_date LIKE '__/__/____' AND SUBSTRING(snapshot_date, 4, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 101)
WHEN snapshot_date LIKE '__/__/____' AND LEFT(snapshot_date, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 103)
WHEN snapshot_date LIKE '__-__-____' AND SUBSTRING(snapshot_date, 4, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 110)
WHEN snapshot_date LIKE '__-__-____' AND LEFT(snapshot_date, 2) > 12 THEN TRY_CONVERT(DATE, snapshot_date, 105)
ELSE TRY_CONVERT(DATE, snapshot_date)
END as snapshot_date
,CASE
WHEN TRY_CONVERT(INT, product_id) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, product_id)
END as product_id
,CASE
WHEN product_name IS NULL OR product_name = '' THEN 'Unknown'
ELSE TRIM(product_name)
END as product_name
,CASE
WHEN sku IS NULL OR sku = '' THEN 'Unknown'
ELSE TRIM(sku)
END as sku
,CASE
WHEN TRIM(LOWER(category)) = 'electronics' THEN 'Electronics'
WHEN TRIM(LOWER(category)) = 'clothing' THEN 'Clothing'
WHEN TRIM(LOWER(category)) = 'kitchen' THEN 'Kitchen'
WHEN TRIM(LOWER(category)) = 'office' THEN 'Office'
WHEN TRIM(LOWER(category)) = 'sports' THEN 'Sports'
WHEN TRIM(LOWER(category)) = 'health' THEN 'Health'
WHEN TRIM(LOWER(category)) = 'beauty' THEN 'Beauty'
WHEN TRIM(LOWER(category)) = 'footwear' THEN 'Footwear'
WHEN TRIM(LOWER(category)) = 'toys' THEN 'Toys'
WHEN TRIM(LOWER(category)) = 'bags' THEN 'Bags'
ELSE 'Unknown'
END AS category
,CASE
WHEN TRY_CONVERT(INT, stock_on_hand) IS NULL OR stock_on_hand < 0 THEN NULL
ELSE TRY_CONVERT(INT, stock_on_hand)
END AS stock_on_hand
,CASE
WHEN stock_reserved < 0 OR TRY_CONVERT(INT, stock_reserved) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, stock_reserved)
END as stock_reserved
,CASE
WHEN reorder_level IS NULL OR reorder_level < 0 OR TRY_CONVERT(INT, reorder_level) IS NULL THEN NULL
ELSE TRY_CONVERT(INT, reorder_level)
END as reorder_level
,CASE
WHEN unit_cost LIKE '$%' THEN TRY_CONVERT(DECIMAL(10, 2), SUBSTRING(unit_cost, 2, LEN(unit_cost)))
ELSE TRY_CONVERT(DECIMAL(10, 2), unit_cost)
END as unit_cost
,CASE
WHEN TRY_CONVERT(DECIMAL(10,2), unit_price) IS NULL THEN TRY_CONVERT(DECIMAL(10,2), REPLACE(REPLACE(unit_price, ',', ''), '$', ''))
ELSE TRY_CONVERT(DECIMAL(10, 2), unit_price)
END as unit_price
,CASE
WHEN warehouse_location IS NULL OR warehouse_location = '' THEN 'Unknown'
ELSE UPPER(warehouse_location)
END as warehouse_location
,[store_id]
FROM [bronze].[inventory_snapshots]
)t;