-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path03_data_cleaning.sql
More file actions
164 lines (151 loc) · 4.95 KB
/
Copy path03_data_cleaning.sql
File metadata and controls
164 lines (151 loc) · 4.95 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
-- =====================================================
-- DATA CLEANING & DATA LOADING
-- Superstore Sales Analysis
-- =====================================================
-- =====================================================
-- SECTION 1: Split Shipment Handling
-- =====================================================
-- During exploration, repeated order-product combinations
-- were identified in the source dataset.
--
-- Investigation showed that sales, profit and quantity
-- values differed across records, indicating legitimate
-- split shipments rather than duplicate entries.
--
-- Decision:
-- Preserve all transaction records to maintain
-- transaction-level accuracy and prevent loss of
-- business information.
-- =====================================================
-- SECTION 2: Customer Dimension Loading
-- =====================================================
-- Customer information was separated into a dedicated
-- dimension table to eliminate redundancy and support
-- customer-level analysis.
--
-- Location attributes excluded from this table
-- as they describe the delivery location per order
-- not the permanent customer profile.
-- Geographic attributes loaded into orders dimension.
INSERT INTO customers (
customer_id,
customer_name,
segment
)
SELECT DISTINCT customer_id, customer_name, segment
FROM raw_sales;
-- =====================================================
-- SECTION 3: Product Dimension Loading
-- =====================================================
-- Product information was separated into a dedicated
-- dimension table to support category and sub-category
-- analysis while reducing duplication across transactions.
--
-- Product identifier inconsistencies were identified
-- during exploration.
-- DISTINCT applied on both product_id and product_name
-- to capture all unique product combinations.
-- product_key auto generates as surrogate PRIMARY KEY.
INSERT INTO products (
product_id,
product_name,
category,
sub_category
)
SELECT DISTINCT product_id, product_name, category, sub_category
FROM raw_sales;
-- =====================================================
-- SECTION 4: Orders Dimension Loading
-- =====================================================
-- Order-level attributes and geographic information
-- were isolated into an Orders dimension to support
-- regional and shipping analysis.
--
-- Geographic attributes placed here because location
-- describes delivery destination per transaction
-- not permanent customer address.
--
-- row_id used as surrogate PRIMARY KEY because
-- order_id appeared multiple times in source data
-- due to split shipments.
-- DISTINCT applied to create unique order-level records
-- for the Orders dimension.
INSERT INTO orders (
order_id,
order_date,
ship_date,
ship_mode,
customer_id,
country,
city,
state,
postal_code,
region
)
SELECT DISTINCT order_id, order_date, ship_date, ship_mode,
customer_id, country, city, state,
postal_code, region
FROM raw_sales;
-- =====================================================
-- SECTION 5: Sales Fact Table Loading
-- =====================================================
-- The sales fact table stores transaction-level business
-- metrics including sales, profit, quantity and discount.
--
-- Product records were mapped using both product_id and
-- product_name to ensure accurate assignment of product_key
-- despite identifier inconsistencies discovered during
-- exploration.
--
-- No DISTINCT operation was applied during fact loading
-- because valid split shipment transactions must be
-- preserved at transaction level.
INSERT INTO sales (
customer_id,
order_id,
product_key,
quantity,
sales,
profit,
discount
)
SELECT
r.customer_id,
r.order_id,
p.product_key,
r.quantity,
r.sales,
r.profit,
r.discount
FROM raw_sales r
JOIN products p
ON r.product_id = p.product_id
AND r.product_name = p.product_name;
-- =====================================================
-- SECTION 6: Data Validation
-- =====================================================
-- Validation checks were performed after loading to
-- ensure that all dimension and fact tables were
-- populated successfully.
SELECT COUNT(*) AS customer_count FROM customers;
SELECT COUNT(*) AS product_count FROM products;
SELECT COUNT(*) AS order_count FROM orders;
SELECT COUNT(*) AS sales_count FROM sales;
-- Null check on fact table key columns
SELECT COUNT(*) AS null_keys FROM sales
WHERE product_key IS NULL
OR order_id IS NULL
OR customer_id IS NULL;
-- Expected result: 0
-- Surrogate key mapping validation
-- Confirms every raw_sales record
-- successfully matched to a product_key
SELECT COUNT(*) AS unmatched_products
FROM raw_sales r
LEFT JOIN products p
ON r.product_id = p.product_id
AND r.product_name = p.product_name
WHERE p.product_key IS NULL;
-- Expected result: 0
-- Any value above 0 indicates data loss
-- during sales fact table loading