Description
Table: Customers
| Column Name | Type |
|---|---|
| customer_id | int |
| customer_name | varchar |
| varchar |
customer_idis the column of unique values for this table.- Each row of this table contains the name and the email of a customer of an online shop.
Table: Contacts
| Column Name | Type |
|---|---|
| user_id | id |
| contact_name | varchar |
| contact_email | varchar |
(user_id, contact_email)is the primary key (combination of columns with unique values) for this table.- Each row of this table contains the name and email of one contact of customer with
user_id. - This table contains information about people each customer trust. The contact may or may not exist in the
Customerstable.
Table: Invoices
| Column Name | Type |
|---|---|
| invoice_id | int |
| price | int |
| user_id | int |
invoice_idis the column of unique values for this table.- Each row of this table indicates that
user_idhas an invoice withinvoice_idand aprice.
Problem Statement
Write a solution to find the following for each invoice_id:
- customer_name: The name of the customer the invoice is related to.
- price: The price of the invoice.
- contacts_cnt: The number of contacts related to the customer.
- trusted_contacts_cnt: The number of contacts related to the customer and at the same time they are customers to the shop. (i.e their email exists in the Customers table.)
Return the result table ordered by invoice_id.
The result format is in the following example.
Example 1:
Input:
Customerstable:
| customer_id | customer_name | |
|---|---|---|
| 1 | Alice | alice@leetcode.com |
| 2 | Bob | bob@leetcode.com |
| 13 | John | john@leetcode.com |
| 6 | Alex | alex@leetcode.com |
Contactstable:
| user_id | contact_name | contact_email |
|---|---|---|
| 1 | Bob | bob@leetcode.com |
| 1 | John | john@leetcode.com |
| 1 | Jal | jal@leetcode.com |
| 2 | Omar | omar@leetcode.com |
| 2 | Meir | meir@leetcode.com |
| 6 | Alice | alice@leetcode.com |
Invoicestable:
| invoice_id | price | user_id |
|---|---|---|
| 77 | 100 | 1 |
| 88 | 200 | 1 |
| 99 | 300 | 2 |
| 66 | 400 | 2 |
| 55 | 500 | 13 |
| 44 | 60 | 6 |
Output:
| invoice_id | customer_name | price | contacts_cnt | trusted_contacts_cnt |
|---|---|---|---|---|
| 44 | Alex | 60 | 1 | 1 |
| 55 | John | 500 | 0 | 0 |
| 66 | Bob | 400 | 2 | 0 |
| 77 | Alice | 100 | 3 | 2 |
| 88 | Alice | 200 | 3 | 2 |
| 99 | Bob | 300 | 2 | 0 |
Explanation:
- Alice has three contacts, two of them are trusted contacts (Bob and John).
- Bob has two contacts, none of them is a trusted contact.
- Alex has one contact and it is a trusted contact (Alice).
- John doesn’t have any contacts.
Solution
The problem can be separate into separate subproblems. The output must contains all records from Invoices table. Hence, that will be the first reference table.
- Join
InvoiceswithCustomersso that you can have information about each customer’s name.
1SELECT invoice_id, customer_name, price
2 FROM Invoices i
3 LEFT OUTER JOIN Customers c ON i.user_id = c.customer_id
4 ORDER BY invoice_id;
This gives us the first three columns of the output expected.
| invoice_id | customer_name | price |
|---|---|---|
| 44 | Alex | 60 |
| 55 | John | 500 |
| 66 | Bob | 400 |
| 77 | Alice | 100 |
| 88 | Alice | 200 |
| 99 | Bob | 300 |
- Next, you need information on contacts which you can get by joining with
Contactstable.
1SELECT invoice_id, customer_name, price, contact_name
2 FROM Invoices i
3 LEFT OUTER JOIN Customers c ON i.user_id = c.customer_id
4 LEFT OUTER JOIN Contacts co ON co.user_id = c.customer_id
5 ORDER BY invoice_id;
This produces below results.
| invoice_id | customer_name | price | contact_name |
|---|---|---|---|
| 44 | Alex | 60 | Alice |
| 55 | John | 500 | null |
| 66 | Bob | 400 | Meir |
| 66 | Bob | 400 | Omar |
| 77 | Alice | 100 | Jal |
| 77 | Alice | 100 | John |
| 77 | Alice | 100 | Bob |
| 88 | Alice | 200 | Jal |
| 88 | Alice | 200 | John |
| 88 | Alice | 200 | Bob |
| 99 | Bob | 300 | Meir |
| 99 | Bob | 300 | Omar |
If you look at these results and calculate the count of contact_name per invoice_id, you will find the contacts_cnt.
1SELECT i.invoice_id, c.customer_name, i.price, COUNT(co.contact_name) AS contacts_cnt
2 FROM Invoices i
3 LEFT JOIN Customers c ON i.user_id = c.customer_id
4 LEFT JOIN Contacts co ON co.user_id = c.customer_id
5 GROUP BY i.invoice_id
6 ORDER BY i.invoice_id;
| invoice_id | customer_name | price | contacts_cnt |
|---|---|---|---|
| 44 | Alex | 60 | 1 |
| 55 | John | 500 | 0 |
| 66 | Bob | 400 | 2 |
| 77 | Alice | 100 | 3 |
| 88 | Alice | 200 | 3 |
| 99 | Bob | 300 | 2 |
This produces the fourth column contacts_cnt. Now, the only remaining column is trusted_contacts_cnt. These are the customers which exist in the Customers table. So, you need to join with Customers table again using customer_name field. This produces the final result.
1SELECT i.invoice_id, c.customer_name, i.price,
2 COUNT(co.contact_name) AS contacts_cnt,
3 COUNT(cust.customer_name) AS trusted_contacts_cnt
4 FROM Invoices i
5 LEFT JOIN Customers c ON i.user_id = c.customer_id
6 LEFT JOIN Contacts co ON co.user_id = c.customer_id
7 LEFT JOIN Customers cust ON cust.customer_name = co.contact_name
8 GROUP BY i.invoice_id
9 ORDER BY i.invoice_id;


Comments