Write SQL and Python, run instantly in your browser, and track your progress.
You are a data engineer at Wayfair. You are responsible for building the core data models for the company's new data warehouse. Your current task is to build the fct_order_items table, which will be the source of truth for all sales analysis.
This requires joining the raw order_items and products tables, and then cleaning and standardizing the data. The final table should only contain items from active products, with valid prices and quantities, and exclude any items that were canceled or returned.
Your query should produce this clean, standardized feed, sorted by product category.
| Column Name | Type |
|---|---|
| order_item_id |
You are a data engineer at Wayfair. You are responsible for building the core data models for the company's new data warehouse. Your current task is to build the fct_order_items table, which will be the source of truth for all sales analysis.
This requires joining the raw order_items and products tables, and then cleaning and standardizing the data. The final table should only contain items from active products, with valid prices and quantities, and exclude any items that were canceled or returned.
Your query should produce this clean, standardized feed, sorted by product category.
| Column Name | Type |
|---|---|
| order_item_id |
| INTEGER |
| INTEGER |
| order_id | INTEGER |
| order_id | INTEGER |
| product_id | INTEGER |
| product_id | INTEGER |
| quantity | INTEGER |
| quantity | INTEGER |
| unit_price | REAL |
| unit_price | REAL |
| line_subtotal | REAL |
| line_subtotal | REAL |
| tax_amount | REAL |
| tax_amount | REAL |
| discount_amount | REAL |
| discount_amount | REAL |
| fulfillment_status | TEXT |
| fulfillment_status | TEXT |
| return_requested_at | TEXT |
| return_requested_at | TEXT |
| return_reason | TEXT |
| return_reason | TEXT |
| order_item_id | order_id | product_id | quantity | unit_price | line_subtotal | tax_amount | discount_amount | fulfillment_status | return_requested_at | return_reason |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 10 | 1 |
| order_item_id | order_id | product_id | quantity | unit_price | line_subtotal | tax_amount | discount_amount | fulfillment_status | return_requested_at | return_reason |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | 10 | 1 |
| Column Name | Type |
|---|---|
| product_id | INTEGER |
| sku | TEXT |
| product_name | TEXT |
| category | TEXT |
| price | REAL |
| currency | TEXT |
| Column Name | Type |
|---|---|
| product_id | INTEGER |
| sku | TEXT |
| product_name | TEXT |
| category | TEXT |
| price | REAL |
| currency | TEXT |
| product_id | sku | product_name | category | price | currency | is_active | weight_kg | created_at |
|---|---|---|---|---|---|---|---|---|
| 1 | SKU-10001 | Casper Original Mattress Queen | Home | 1095.0 | USD |
| product_id | sku | product_name | category | price | currency | is_active | weight_kg | created_at |
|---|---|---|---|---|---|---|---|---|
| 1 | SKU-10001 | Casper Original Mattress Queen | Home | 1095.0 | USD |
| order_item_id | normalized_sku | category_upper | fulfillment_upper | line_cents |
|---|---|---|---|---|
| 8 | SKU10019 | APPAREL | SHIPPED | 15675 |
| 44 | SKU10046 | APPAREL | ALLOCATED | 59844 |
| 46 | SKU10046 | APPAREL | DELIVERED | 45426 |
| order_item_id | normalized_sku | category_upper | fulfillment_upper | line_cents |
|---|---|---|---|---|
| 8 | SKU10019 | APPAREL | SHIPPED | 15675 |
| 44 | SKU10046 | APPAREL | ALLOCATED | 59844 |
| 46 | SKU10046 | APPAREL | DELIVERED | 45426 |
Showing first 5 of 99 rows. Order items for active products with normalized data sorted by category.
Showing first 5 of 99 rows. Order items for active products with normalized data sorted by category.
Your final output should be a result set that meets the following requirements:
1. Joining:
order_items table must be joined with the products table on product_id.2. Filtering:
products table, include only items where is_active is 1 and the currency is 'USD' (case-insensitive).order_items table, include only items where and are both greater than 0.Your final output should be a result set that meets the following requirements:
1. Joining:
order_items table must be joined with the products table on product_id.2. Filtering:
products table, include only items where is_active is 1 and the currency is 'USD' (case-insensitive).order_items table, include only items where and are both greater than 0.| 50.96 |
| 50.96 |
| 50.96 |
| 50.96 |
| 4.14 |
| 4.14 |
| 0.0 |
| 0.0 |
| shipped |
| shipped |
| 2 | 2 | 8 | 3 | 200.51 | 601.53 | 53.2 | 0.0 | delivered |
| 2 | 2 | 8 | 3 | 200.51 | 601.53 | 53.2 | 0.0 | delivered |
| 3 | 3 | 44 | 2 | 34.13 | 68.26 | 6.25 | 0.99 | shipped |
| 3 | 3 | 44 | 2 | 34.13 | 68.26 | 6.25 | 0.99 | shipped |
| 4 | 4 | 47 | 1 | 290.99 | 290.99 | 23.29 | 0.0 | shipped |
| 4 | 4 | 47 | 1 | 290.99 | 290.99 | 23.29 | 0.0 | shipped |
| 5 | 5 | 36 | 3 | 189.87 | 569.61 | 46.78 | 79.38 | backordered |
| 5 | 5 | 36 | 3 | 189.87 | 569.61 | 46.78 | 79.38 | backordered |
| is_active | INTEGER |
| is_active | INTEGER |
| weight_kg | REAL |
| weight_kg | REAL |
| created_at | TEXT |
| created_at | TEXT |
| 1 |
| 1 |
| 31.75 |
| 31.75 |
| 2025-02-14 10:57:38 |
| 2025-02-14 10:57:38 |
| 2 | SKU-10002 | Dyson Supersonic Hair Dryer | Beauty | 429.99 | USD | 1 | 0.66 | 2025-02-27 07:20:29 |
| 2 | SKU-10002 | Dyson Supersonic Hair Dryer | Beauty | 429.99 | USD | 1 | 0.66 | 2025-02-27 07:20:29 |
| 3 | SKU-10003 | CalDigit TS4 Thunderbolt Dock | Office | 399.99 | USD | 1 | 0.5 | 2024-12-11 00:49:57 |
| 3 | SKU-10003 | CalDigit TS4 Thunderbolt Dock | Office | 399.99 | USD | 1 | 0.5 | 2024-12-11 00:49:57 |
| 4 | SKU-10004 | Under Armour Tech 2.0 T-Shirt | Sports | 25.0 | USD | 1 | 0.15 | 2024-11-22 04:49:00 |
| 4 | SKU-10004 | Under Armour Tech 2.0 T-Shirt | Sports | 25.0 | USD | 1 | 0.15 | 2024-11-22 04:49:00 |
| 5 | SKU-10005 | Staples TRU RED Copy Paper 10-Ream | Office | 54.99 | USD | 1 | 22.68 | 2025-01-10 01:43:59 |
| 5 | SKU-10005 | Staples TRU RED Copy Paper 10-Ream | Office | 54.99 | USD | 1 | 22.68 | 2025-01-10 01:43:59 |
| 57 | SKU10026 | APPAREL | SHIPPED | 7941 |
| 57 | SKU10026 | APPAREL | SHIPPED | 7941 |
| 88 | SKU10019 | APPAREL | DELIVERED | 7091 |
| 88 | SKU10019 | APPAREL | DELIVERED | 7091 |
quantityquantityunit_priceunit_pricefulfillment_status is 'CANCELED' or 'RETURNED' (case-insensitive).fulfillment_status is 'CANCELED' or 'RETURNED' (case-insensitive).3. Transformations:
3. Transformations:
normalized_sku by taking the sku, removing all hyphens, and converting it to uppercase.category_upper column by converting category to uppercase.fulfillment_upper column by converting fulfillment_status to uppercase.line_cents column by converting the line_subtotal to an integer representing cents.normalized_sku by taking the sku, removing all hyphens, and converting it to uppercase.category_upper column by converting category to uppercase.fulfillment_upper column by converting fulfillment_status to uppercase.line_cents column by converting the line_subtotal to an integer representing cents.4. Columns:
4. Columns:
order_item_idnormalized_skucategory_upperfulfillment_upperline_centsorder_item_idnormalized_skucategory_upperfulfillment_upperline_cents5. Ordering:
5. Ordering:
category_upper in ascending alphabetical order.order_item_id in ascending order.category_upper in ascending alphabetical order.order_item_id in ascending order.