Joins and set operations
Diagnosing duplicate or missing rows after joins
Compare joined row counts with the intended order grain and find unmatched rows.
Lesson 38 of 84
Reading: about 2 min
Lesson + practice: about 12 min
Difficulty: Intermediate
On this page4 sections
This lesson uses the unmodified DDI_SQL_Training dataset v1.0.0 on SQL Server 2019 or later. Compare joined row counts with the intended order grain and find unmatched rows.
Run the example
SELECT o.OrderID, COUNT(*) AS JoinedRows
FROM dbo.Orders AS o
JOIN dbo.OrderItems AS i ON i.OrderID = o.OrderID
WHERE o.OrderID BETWEEN 1 AND 3
GROUP BY o.OrderID
ORDER BY o.OrderID;Read it step by step
- Orders is one row per OrderID; OrderItems is two lines per order in this dataset.
- The join returns one row per line, so each selected OrderID appears twice.
- GROUP BY OrderID counts matches and exposes the cardinality instead of hiding it with DISTINCT.
Check the result
| OrderID | JoinedRows |
|---|---|
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
These are expected repeated order keys, not duplicate source orders.
Practice
Find Orders 1–5 that have no Payment row. Explain why an unmatched order is possible.
Check your answer and expected result
Reveal answer
SELECT o.OrderID, o.OrderStatus
FROM dbo.Orders AS o
LEFT JOIN dbo.Payments AS p ON p.OrderID = o.OrderID
WHERE o.OrderID BETWEEN 1 AND 5 AND p.OrderID IS NULL
ORDER BY o.OrderID;| OrderID | OrderStatus |
|---|---|
| 1 | Cancelled |
| 2 | Pending |
| 5 | Cancelled |
An order without a payment remains in the left join with NULL payment columns. Pending and Cancelled orders need no payment in this dataset.
Your progress
Reveal the check answer or reach the end to complete this lesson.