Advanced SQL · Course lab · about 150 minutes · 6 tasks · marked out of 100, pass at 60
Find the wrong number in a chain store's sales report
The situation
A shoe retailer with branches in Lahore, Karachi and Faisalabad reports monthly revenue from a SQL query an intern wrote two years ago. The finance manager suspects the figures are wrong, because the Karachi number jumped when a second delivery address was added for some customers.
Rebuild the report so that every number can be defended, explain where the old one went wrong, and make it fast and safe to run.
What you'll be able to show
- Detect silent row loss and silent row multiplication in joins
- Use window functions for rankings, running totals and month-on-month change
- Restructure a nested query into named CTE steps a colleague can read
- Read a query plan, add an index, and prove the change
What you need
- SQLite (DB Browser for SQLite), MySQL or PostgreSQL; any one is fine
- The four tables you will create below, with invented but realistic data
Tasks
-
1Build the data, with the trap in it
Create customers (id, name, city), addresses (customer_id, address), orders (id, customer_id, branch, order_date, amount) and products. Insert at least 40 orders over three months. Give five customers two addresses, and leave three orders pointing at a customer id that does not exist.A correct result: Row counts for each table, and a note naming which five customers have two addresses and which three orders are orphans. -
2Reproduce the wrong report
Write the intern's query: orders INNER JOIN customers INNER JOIN addresses, SUM(amount) by branch and month. Then write the correct total from orders alone.A correct result: Two sets of totals side by side, and the difference explained: which rows were multiplied and which were lost. -
3Fix it and prove it
Rewrite the report so every order is counted exactly once: LEFT JOIN where you are counting orders, and never join to a table whose key is not unique for the grain you report at. Check row counts before and after each join.A correct result: Branch-month totals that match SUM(amount) from orders exactly, with the before-and-after row counts written beside each join. -
4Rank and compare with windows
Using window functions: the top three customers by revenue in each branch, a running total of revenue by month for each branch, and each month's change from the previous month (LAG).A correct result: Three result sets, each produced by one query with a window clause and no self join. -
5Make it readable
Rewrite the final report as a chain of named CTEs (for example clean_orders, monthly_branch, ranked). Add one comment line above each step saying what business rule it applies.A correct result: A query a colleague can read top to bottom, with no step called t1 or x. -
6Make it fast and safe
Run the plan (EXPLAIN or EXPLAIN QUERY PLAN) on the report, add an index on orders(customer_id) or orders(branch, order_date), and run it again. Then write the one-off correction for the three orphan orders as a SELECT first, then inside a transaction.A correct result: Both plans with the change named, and the SELECT that preceded the UPDATE or DELETE, wrapped in a transaction.
What to hand in
One .sql file with every statement in order and comments, plus a one-page note to the finance manager: what was wrong, by how much, and how the new report prevents it.
How it is marked
| Criterion | Points |
|---|---|
| Both join faults reproduced and explained with numbers | 25 |
| Corrected report reconciles exactly with the orders table | 25 |
| Window functions used correctly for rank, running total and change | 20 |
| Readable CTE structure with business-rule comments | 15 |
| Plan read before and after an index; correction run safely | 15 |
| Total · pass at 60 | 100 |
صورتحال
لاہور، کراچی اور فیصل آباد میں برانچوں والا جوتوں کا ایک ریٹیلر ماہانہ آمدنی ایک ایسی SQL کوئری سے رپورٹ کرتا ہے جو دو سال پہلے ایک انٹرن نے لکھی تھی۔ فنانس منیجر کو شک ہے کہ اعداد غلط ہیں، کیونکہ جب کچھ گاہکوں کا دوسرا ڈیلیوری پتا شامل ہوا تو کراچی کا عدد اچانک بڑھ گیا۔
رپورٹ دوبارہ بنائیں تاکہ ہر عدد کا دفاع ہو سکے، بتائیں پرانی کہاں غلط ہوئی، اور اسے چلانے میں تیز اور محفوظ بنائیں۔
آپ کیا دکھا سکیں گے
- joins میں خاموش قطاروں کی کمی اور خاموش قطاروں کی ضرب پکڑنا
- درجہ بندی، چلتے مجموعے اور ماہ بہ ماہ تبدیلی کے لیے window functions استعمال کرنا
- گہری کوئری کو نام والے CTE قدموں میں بدلنا جنہیں ساتھی پڑھ سکے
- کوئری پلان پڑھنا، انڈیکس لگانا، اور تبدیلی ثابت کرنا
آپ کو کیا چاہیے
- SQLite (DB Browser for SQLite)، MySQL یا PostgreSQL؛ کوئی ایک کافی ہے
- نیچے بنائی جانے والی چار جدولیں، فرضی مگر حقیقت پسندانہ ڈیٹا کے ساتھ
کام
-
1ڈیٹا بنائیں، جال سمیت
customers (id, name, city)، addresses (customer_id, address)، orders (id, customer_id, branch, order_date, amount) اور products بنائیں۔ تین مہینوں میں کم از کم 40 آرڈر ڈالیں۔ پانچ گاہکوں کو دو پتے دیں، اور تین آرڈر ایسے گاہک id کی طرف رکھیں جو موجود نہیں۔درست نتیجہ: ہر جدول کی قطاروں کی تعداد، اور ایک نوٹ جو بتائے کن پانچ گاہکوں کے دو پتے ہیں اور کون سے تین آرڈر یتیم ہیں۔ -
2غلط رپورٹ دوبارہ بنائیں
انٹرن والی کوئری لکھیں: orders INNER JOIN customers INNER JOIN addresses، برانچ اور مہینے کے لحاظ سے SUM(amount)۔ پھر صرف orders سے درست مجموعہ لکھیں۔درست نتیجہ: دونوں مجموعے ساتھ ساتھ، اور فرق کی وضاحت: کون سی قطاریں دگنی ہوئیں اور کون سی غائب۔ -
3ٹھیک کریں اور ثابت کریں
رپورٹ ایسے لکھیں کہ ہر آرڈر بالکل ایک بار گنا جائے: جہاں آرڈر گن رہے ہیں وہاں LEFT JOIN، اور کبھی ایسی جدول سے join نہیں جس کی کلید آپ کی رپورٹ کی سطح پر منفرد نہ ہو۔ ہر join سے پہلے اور بعد قطاریں گنیں۔درست نتیجہ: برانچ اور مہینے کے مجموعے جو orders کے SUM(amount) سے بالکل ملیں، ہر join کے ساتھ پہلے اور بعد کی قطاروں کی تعداد لکھی ہو۔ -
4windows سے درجہ بندی اور موازنہ
window functions سے: ہر برانچ میں آمدنی کے لحاظ سے پہلے تین گاہک، ہر برانچ کے لیے مہینے کے لحاظ سے آمدنی کا چلتا مجموعہ، اور ہر مہینے کی پچھلے مہینے سے تبدیلی (LAG)۔درست نتیجہ: تین نتائج، ہر ایک window clause والی ایک کوئری سے، بغیر self join کے۔ -
5پڑھنے لائق بنائیں
آخری رپورٹ کو نام والے CTEs کی زنجیر کے طور پر دوبارہ لکھیں (مثلاً clean_orders، monthly_branch، ranked)۔ ہر قدم کے اوپر ایک تبصرے کی سطر لکھیں کہ یہ کون سا کاروباری اصول لاگو کرتا ہے۔درست نتیجہ: ایسی کوئری جسے ساتھی اوپر سے نیچے پڑھ سکے، اور کوئی قدم t1 یا x نام کا نہ ہو۔ -
6تیز اور محفوظ بنائیں
رپورٹ پر پلان چلائیں (EXPLAIN یا EXPLAIN QUERY PLAN)، orders(customer_id) یا orders(branch, order_date) پر انڈیکس لگائیں، اور دوبارہ چلائیں۔ پھر تین یتیم آرڈرز کی یک بار درستی پہلے SELECT کے طور پر لکھیں، پھر ٹرانزیکشن کے اندر۔درست نتیجہ: دونوں پلان اور تبدیلی کا نام، اور وہ SELECT جو UPDATE یا DELETE سے پہلے آیا، ٹرانزیکشن میں لپٹا ہوا۔
کیا جمع کروانا ہے
ایک .sql فائل جس میں ہر بیان ترتیب سے اور تبصروں کے ساتھ ہو، اور فنانس منیجر کے نام ایک صفحے کا نوٹ: کیا غلط تھا، کتنا، اور نئی رپورٹ اسے کیسے روکتی ہے۔
نمبر کیسے ملیں گے
| معیار | نمبر |
|---|---|
| دونوں join کی خرابیاں اعداد کے ساتھ دوبارہ بنائی اور سمجھائی گئیں | 25 |
| درست رپورٹ orders جدول سے بالکل ملتی ہے | 25 |
| درجہ بندی، چلتے مجموعے اور تبدیلی کے لیے window functions درست استعمال ہوئے | 20 |
| کاروباری اصول کے تبصروں کے ساتھ پڑھنے لائق CTE ڈھانچہ | 15 |
| انڈیکس سے پہلے اور بعد پلان پڑھا گیا؛ درستی محفوظ طریقے سے چلائی گئی | 15 |
| کل · پاس 60 | 100 |
Hand in your lab
Create a free BvLogic ID to hand in your lab, get it marked, and have it on your certificate.
Create your BvLogic IDAlready have one? Sign in and this course will be added to it.