{x}
blog image

Customer Who Visited but Did Not Make Any Transactions

Table: Visits

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| visit_id    | int     |
| customer_id | int     |
+-------------+---------+
visit_id is the column with unique values for this table.
This table contains information about the customers who visited the mall.

 

Table: Transactions

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| transaction_id | int     |
| visit_id       | int     |
| amount         | int     |
+----------------+---------+
transaction_id is column with unique values for this table.
This table contains information about the transactions made during the visit_id.

 

Write a solution to find the IDs of the users who visited without making any transactions and the number of times they made these types of visits.

Return the result table sorted in any order.

The result format is in the following example.

 

Example 1:

Input: 
Visits
+----------+-------------+
| visit_id | customer_id |
+----------+-------------+
| 1        | 23          |
| 2        | 9           |
| 4        | 30          |
| 5        | 54          |
| 6        | 96          |
| 7        | 54          |
| 8        | 54          |
+----------+-------------+
Transactions
+----------------+----------+--------+
| transaction_id | visit_id | amount |
+----------------+----------+--------+
| 2              | 5        | 310    |
| 3              | 5        | 300    |
| 9              | 5        | 200    |
| 12             | 1        | 910    |
| 13             | 2        | 970    |
+----------------+----------+--------+
Output: 
+-------------+----------------+
| customer_id | count_no_trans |
+-------------+----------------+
| 54          | 2              |
| 30          | 1              |
| 96          | 1              |
+-------------+----------------+
Explanation: 
Customer with id = 23 visited the mall once and made one transaction during the visit with id = 12.
Customer with id = 9 visited the mall once and made one transaction during the visit with id = 13.
Customer with id = 30 visited the mall once and did not make any transactions.
Customer with id = 54 visited the mall three times. During 2 visits they did not make any transactions, and during one visit they made 3 transactions.
Customer with id = 96 visited the mall once and did not make any transactions.
As we can see, users with IDs 30 and 96 visited the mall one time without making any transactions. Also, user 54 visited the mall twice and did not make any transactions.

Solution Explanation for LeetCode Problem 1581: Customer Who Visited but Did Not Make Any Transactions

This problem requires finding customers who visited a mall but didn't make any transactions, along with the number of such visits for each customer. We are given two tables: Visits (containing visit_id and customer_id) and Transactions (containing transaction_id, visit_id, and amount).

Two approaches are presented, both using SQL:

Approach 1: Subquery

This approach uses a subquery to identify visit_ids without any associated transactions in the Transactions table. The outer query then joins this result with the Visits table to find the corresponding customer_id and counts the occurrences of each customer.

MySQL Code:

SELECT customer_id, COUNT(*) AS count_no_trans
FROM Visits
WHERE visit_id NOT IN (SELECT visit_id FROM Transactions)
GROUP BY customer_id;

Explanation:

  1. Inner Query (SELECT visit_id FROM Transactions): This selects all visit_ids that have at least one transaction record.
  2. Outer Query (WHERE visit_id NOT IN (...)): This filters the Visits table, keeping only rows where visit_id is not present in the result of the inner query. This effectively selects visits without any transactions.
  3. GROUP BY customer_id: This groups the results by customer_id, allowing us to count the number of visits without transactions for each customer.
  4. COUNT(*) AS count_no_trans: This counts the number of visits in each group and names the resulting column count_no_trans.

Time Complexity: The time complexity depends on the database engine's optimization but is generally considered O(N + M), where N is the number of rows in Visits and M is the number of rows in Transactions. The NOT IN subquery might lead to a full table scan in some cases, affecting performance on very large datasets.

Approach 2: Left Join

This approach utilizes a LEFT JOIN to combine the Visits and Transactions tables. By checking for NULL values in the amount column (from the Transactions table), we can identify visits without any transactions.

MySQL Code:

SELECT v.customer_id, COUNT(*) AS count_no_trans
FROM Visits v
LEFT JOIN Transactions t ON v.visit_id = t.visit_id
WHERE t.amount IS NULL
GROUP BY v.customer_id;

Explanation:

  1. LEFT JOIN: This joins Visits (aliased as v) with Transactions (aliased as t) based on visit_id. A LEFT JOIN ensures that all rows from Visits are included in the result, even if there's no matching row in Transactions.
  2. WHERE t.amount IS NULL: This filters the result to include only rows where there is no matching transaction (amount will be NULL if there's no corresponding entry in Transactions).
  3. GROUP BY v.customer_id: This groups the results by customer_id to count visits without transactions per customer.
  4. COUNT(*) AS count_no_trans: This counts the rows in each group.

Time Complexity: Similar to Approach 1, the time complexity is generally O(N + M), depending on the database engine's optimization. A well-optimized LEFT JOIN typically performs better than a NOT IN subquery with a large dataset. However, the specific performance can vary based on indexing and database implementation.

In summary: Both approaches solve the problem correctly. Approach 2 (using LEFT JOIN) is generally preferred for better performance, especially with large datasets, as it avoids the potential performance issues associated with NOT IN subqueries. However, the actual performance difference may depend on the specific database system and its optimization strategies.