Distinct Customer-City Pairs Present

← Back to SQL Problems

The SQL DISTINCT keyword removes duplicate rows from a query's result set, keeping only one copy of each unique combination of the selected columns. In this problem, that means: given every customer's city and country, return each unique pair exactly once — not every unique city, and not every unique country, but every unique combination of the two together.

This distinction is exactly why interviewers ask it. DISTINCT looks trivial in isolation, but multi-column DISTINCT trips up candidates who assume it behaves like it would on a single column. A city name can repeat across different countries, and a country obviously has many cities, so the only way to know how many truly unique city/country combinations exist is to treat the whole row — every selected column together — as the unit of uniqueness. Interviewers use this problem to check whether a candidate actually understands that model, rather than having memorized the keyword.

The pattern shows up constantly in real analytics work: counting unique visitor/page pairs in web analytics, unique customer/city pairs for a sales-coverage report, unique product/category combinations in a catalog, or unique user/device pairs in a login audit. Anywhere "how many distinct combinations of X and Y do we actually have" is the business question, DISTINCT — or its aggregate cousin, GROUP BY — is the tool.

It's worth being precise about the difference between a duplicate row and a duplicate value: a duplicate value just means the same city name appears more than once in the table; a duplicate row (in the sense DISTINCT cares about) means every selected column matches another row exactly. DISTINCT only ever removes duplicate rows from the result — it can't and won't deduplicate one column while ignoring another. Use DISTINCT when you need unique combinations for display or export; reach for GROUP BY the moment you also need a count or aggregate per group.

Easy ⏱ 8 min 77% acceptance ★★★★★ 4.5

Problem Description

Return the distinct (city, country) pairs appearing among customers, alphabetical by country then city.

Database Schema

13 tables — click to view columns

Use these exact table and column names in your query. Open Schema & Data under the editor to preview sample rows.

customers 5 cols
customer_idINTEGERnameTEXTcityTEXTcountryTEXTsignup_dateDATE
products 4 cols
product_idINTEGERproduct_nameTEXTcategoryTEXTpriceREAL
orders 5 cols
order_idINTEGERcustomer_idINTEGERorder_dateDATEamountREALstatusTEXT
order_items 4 cols
order_idINTEGERproduct_idINTEGERquantityINTEGERunit_priceREAL
payments 5 cols
payment_idINTEGERorder_idINTEGERmethodTEXTamountREALpaid_dateDATE
employees 6 cols
employee_idINTEGERnameTEXTdepartmentTEXTmanager_idINTEGERsalaryREALhire_dateDATE
logins 2 cols
user_idINTEGERlogin_dateDATE
ratings 5 cols
rating_idINTEGERcustomer_idINTEGERproduct_idINTEGERratingINTEGERrating_dateDATE
subscriptions 6 cols
sub_idINTEGERcustomer_idINTEGERplanTEXTstart_dateDATEend_dateDATEmonthly_feeREAL
shipments 5 cols
shipment_idINTEGERorder_idINTEGERcarrierTEXTship_dateDATEdelivery_dateDATE
support_tickets 7 cols
ticket_idINTEGERcustomer_idINTEGERsubjectTEXTpriorityTEXTstatusTEXTopened_dateDATEclosed_dateDATE
coupons 5 cols
codeTEXTdiscount_pctREALmin_order_amountREALvalid_fromDATEvalid_toDATE
coupon_redemptions 4 cols
redemption_idINTEGERcodeTEXTorder_idINTEGERredeemed_dateDATE

Examples

Example 1
Input
customers table (abridged):
customer_id | city      | country
101         | Delhi     | India
102         | Mumbai    | India
103         | Bengaluru | India
201         | Delhi     | India   -- same city+country as customer 101
Output
city      | country
Bengaluru | India
Delhi     | India
Mumbai    | India
Explanation

Customers 101 and 201 are both in Delhi, India — that's the same (city, country) pair, so it appears only once in the output even though two different customers share it.

Constraints

  • Distinct pairs (not just distinct city).
  • Order by country, city.

Topics

DISTINCT

Companies

MetaAirbnb

Hints

Hint 1

DISTINCT applies to the whole row of selected columns, not each independently.

Press Run (or Ctrl+Enter) to execute your query against the sample database.
customers5 cols
  • customer_idINTEGER
  • nameTEXT
  • cityTEXT
  • countryTEXT
  • signup_dateDATE
customer_idnamecitycountrysignup_date
101RahulDelhiIndia2023-01-12
102AmanMumbaiIndia2023-02-03
103SaraBengaluruIndia2023-02-20
products4 cols
  • product_idINTEGER
  • product_nameTEXT
  • categoryTEXT
  • priceREAL
product_idproduct_namecategoryprice
1Wireless MouseElectronics799
2Office ChairFurniture5499
3NotebookStationery149
orders5 cols
  • order_idINTEGER
  • customer_idINTEGER
  • order_dateDATE
  • amountREAL
  • statusTEXT
order_idcustomer_idorder_dateamountstatus
10011012024-01-051598Delivered
10021022024-01-115499Delivered
10031012024-02-02149Cancelled
order_items4 cols
  • order_idINTEGER
  • product_idINTEGER
  • quantityINTEGER
  • unit_priceREAL
order_idproduct_idquantityunit_price
100112799
1002215499
100435149
payments5 cols
  • payment_idINTEGER
  • order_idINTEGER
  • methodTEXT
  • amountREAL
  • paid_dateDATE
payment_idorder_idmethodamountpaid_date
50011001UPI15982024-01-05
50021002Card54992024-01-11
50031005UPI9992024-03-02
employees6 cols
  • employee_idINTEGER
  • nameTEXT
  • departmentTEXT
  • manager_idINTEGER
  • salaryREAL
  • hire_dateDATE
employee_idnamedepartmentmanager_idsalaryhire_date
1MeeraAnalyticsNULL180000
2RohitAnalytics195000
3NehaEngineering1120000
logins2 cols
  • user_idINTEGER
  • login_dateDATE
user_idlogin_date
1012024-06-01
1012024-06-02
1022024-06-01
ratings5 cols
  • rating_idINTEGER
  • customer_idINTEGER
  • product_idINTEGER
  • ratingINTEGER
  • rating_dateDATE
rating_idcustomer_idproduct_idratingrating_date
1101152024-01-10
2101442024-03-12
3102252024-01-15
subscriptions6 cols
  • sub_idINTEGER
  • customer_idINTEGER
  • planTEXT
  • start_dateDATE
  • end_dateDATE
  • monthly_feeREAL
sub_idcustomer_idplanstart_dateend_datemonthly_fee
1101Basic2023-02-012023-07-31499
2101Pro2023-08-01NULL999
3102Pro2023-03-152024-03-14999
shipments5 cols
  • shipment_idINTEGER
  • order_idINTEGER
  • carrierTEXT
  • ship_dateDATE
  • delivery_dateDATE
shipment_idorder_idcarriership_datedelivery_date
11001Delhivery2024-01-062024-01-09
21002BlueDart2024-01-122024-01-14
151018Ekart2024-09-16NULL
support_tickets7 cols
  • ticket_idINTEGER
  • customer_idINTEGER
  • subjectTEXT
  • priorityTEXT
  • statusTEXT
  • opened_dateDATE
  • closed_dateDATE
ticket_idcustomer_idsubjectprioritystatusopened_dateclosed_date
1101Late deliveryHighClosed2024-01-102024-01-11
2102Wrong item receivedHighClosed2024-01-202024-01-23
10110Wrong address deliveredUrgentOpen2024-05-01NULL
coupons5 cols
  • codeTEXT
  • discount_pctREAL
  • min_order_amountREAL
  • valid_fromDATE
  • valid_toDATE
codediscount_pctmin_order_amountvalid_fromvalid_to
WELCOME10105002024-01-012024-12-31
SAVE202020002024-03-012024-06-30
FLASH505010002024-04-012024-04-15
coupon_redemptions4 cols
  • redemption_idINTEGER
  • codeTEXT
  • order_idINTEGER
  • redeemed_dateDATE
redemption_idcodeorder_idredeemed_date
1WELCOME1010012024-01-05
2SAVE2010062024-03-09
3WELCOME1010132024-06-25
Loading expected output…

Understanding DISTINCT in SQL

What is DISTINCT?

DISTINCT is a modifier you add right after SELECT to tell the database "give me only unique rows in the result — collapse any exact duplicates into one." If you select a single column, "unique" means unique values in that column. If you select several columns, "unique" means unique combinations across all of them together — which is exactly the case in this problem, where a (city, country) pair only counts as a duplicate if both values match another row.

Why Interviewers Ask This Question

From a hiring perspective, this is a fast, low-friction way to test something that trips up a surprising number of candidates: whether you understand DISTINCT as a row-level operation. Anyone can recite "DISTINCT removes duplicates." Fewer candidates correctly predict what happens on two or three columns together, and fewer still can cleanly explain when DISTINCT stops being enough and you need GROUP BY instead. It's a small problem that reveals real understanding quickly, which is exactly what a 30-minute interview slot needs.

Real-world Example

This exact shape of problem — deduplicating a combination of columns — shows up constantly outside of interviews too:

Common Mistakes

Time Complexity

Most database engines implement DISTINCT with either a sort (group equal rows together, then walk through and keep the first of each group) or a hash-based approach (bucket rows by a hash of the selected columns and compare within buckets). Both are roughly O(n log n) to O(n) depending on the engine and whether a supporting index exists — in practice, the cost scales with the number of rows scanned before deduplication, not the number of unique rows returned.

Alternative Solution: GROUP BY

Yes — GROUP BY can solve this exact problem:

SELECT city, country
FROM customers
GROUP BY city, country
ORDER BY country, city;

For pure deduplication like this, DISTINCT and GROUP BY city, country return identical results. The difference is intent and flexibility: DISTINCT communicates "just deduplicate this" more directly and is usually marginally simpler to read; GROUP BY is the better choice the moment you also need an aggregate alongside the grouping — for example COUNT(*) per (city, country) pair — since DISTINCT has no equivalent for computing a per-group value. If you don't need a per-group aggregate, prefer DISTINCT for clarity; reach for GROUP BY the moment you do.

SQL Learning Roadmap

DISTINCT sits early in a practical SQL roadmap — right after you're comfortable filtering and sorting, and just before aggregation with GROUP BY. Here's where this problem fits:

Frequently Asked Questions

What is DISTINCT in SQL?

DISTINCT is a keyword used with SELECT to remove duplicate rows from a query's result set, returning only unique combinations of the selected columns.

Can DISTINCT work on multiple columns?

Yes. When DISTINCT is applied to more than one column, uniqueness is evaluated across the whole combination of those columns together, not on each column independently.

What is the difference between DISTINCT and GROUP BY?

DISTINCT simply removes duplicate rows from the output. GROUP BY groups rows that share values so you can run aggregate functions (COUNT, SUM, AVG) per group. If you don't need an aggregate, DISTINCT is simpler; if you do, GROUP BY is the right tool.

Does DISTINCT remove NULL values?

No. SQL treats all NULLs as equal for the purposes of DISTINCT, so a single NULL (or NULL combination) is kept in the result — DISTINCT does not filter NULLs out.

Is DISTINCT expensive to run?

DISTINCT typically requires sorting or hashing the result set to find duplicates, which adds overhead roughly proportional to the number of rows scanned. On an indexed, well-scoped query it is usually fast; on very large unindexed tables it can be one of the more expensive steps in a query plan.

How is DISTINCT usually asked about in interviews?

Interviewers commonly ask candidates to return unique combinations of two or more columns (like this problem), or to explain why COUNT(DISTINCT column) differs from COUNT(column) — testing whether you understand DISTINCT as a row-level, not a single-value, operation.

Can DISTINCT be used with COUNT?

Yes — COUNT(DISTINCT column) counts the number of unique values in a column, ignoring duplicates. This is one of the most common real-world uses of DISTINCT.

Can DISTINCT be used after a JOIN?

Yes, and it is common — joins frequently produce duplicate rows (for example, one customer row repeated once per order), and DISTINCT (or GROUP BY) is often used afterward to collapse those back to unique combinations.

Does column order matter with DISTINCT?

No — SELECT DISTINCT city, country and SELECT DISTINCT country, city return the same set of unique row combinations; only the column order in the output changes, not which rows are considered duplicates.

Should I always add ORDER BY with DISTINCT?

Not strictly required, but strongly recommended — DISTINCT does not guarantee any particular row order, so if the result needs to be presented consistently (as in this problem, ordered by country then city), an explicit ORDER BY is necessary.

Continue Learning SQL

Keep building your SQL foundation — from the basics this problem assumes, through to where DISTINCT leads next:

People Also Solve

Learners who solved this DISTINCT problem also practiced: