SQL - LEFT JOIN, but I want COUNT(*) to only count the results from the INNER part of the join

General Tech Bugs & Fixes 2 years ago

0 10 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Bugs & Fixes related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (10)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

I want to display the number of purchases each customer has made. If they've made 0 purchases, I want to display 0.

 

Desired Output:

 -------------------------------------
| customer_name | number_of_purchases |
 -------------------------------------
|    Marg       |          0          |
|    Ben        |          1          |
|    Phil       |          4          |
|    Steve      |          0          |
 -------------------------------------

Customer Table:

 -----------------------------
| customer_id | customer_name |
 -----------------------------
|      1      |      Marg     |
|      2      |      Ben      |
|      3      |      Phil     |
|      4      |      Steve    |
 -----------------------------

Purchases Table:

 --------------------------------------------------
| purchase_id | customer_id | purchase_description |
 --------------------------------------------------
|      1      |       2     |     500 Reams        |
|      2      |       3     |     6 Toners         |
|      3      |       3     |     20 Staplers      |
|      4      |       3     |     2 Copiers        |
|      5      |       3     |     9 Name Plaques   |
 --------------------------------------------------

My current query is as follows:

SELECT customer_name, COUNT(*) AS number_of_purchaes 
FROM customer 
LEFT JOIN purchases ON customer.customer_id = purchases.customer_id 
GROUP BY customer.customer_id

However, since it's a LEFT JOIN, the query results in rows for customers with no purchases, which makes them part of the COUNT(*). In other words, customers who've made 0 purchases are displayed as having made 1 purchase, like so:

LEFT JOIN Output:

 -------------------------------------
| customer_name | number_of_purchases |
 -------------------------------------
|    Marg       |          1          |
|    Ben        |          1          |
|    Phil       |          4          |
|    Steve      |          1          |
 -------------------------------------

I've also tried an INNER JOIN, but that results in customers with 0 purchases not showing at all:

INNER JOIN Output:

 -------------------------------------
| customer_name | number_of_purchases |
 -------------------------------------
|    Ben        |          1          |
|    Phil       |          4          |
 -------------------------------------

How could I achieve my 

0 views
0 shares
profilepic.png
manpreet 2 years ago

COUNT(*) returns the number of items in a group. This includes NULL values and duplicates.

COUNT(ALL expression) evaluates expression for each row in a group, and returns the number of nonnull values.

CREATE table customer(customer_id integer , customer_name varchar(20));

create table purchases(purchase_id integer , customer_id integer , purchase_description varchar(30));

INSERT INTO customer ( customer_id, customer_name )
VALUES ( 1, 'Marg' )
     , ( 2, 'Ben' )
     , ( 3, 'Phil' )
     , ( 4, 'Steve' );

INSERT INTO purchases ( purchase_id, customer_id, purchase_description )
VALUES ( 1, 2, 'com/tag/5">500 Reams' )
     , ( 2, 3, '6 toners' )
     , ( 3, 3, '20 Staplers' )
     , ( 4, 3, '2 Copiers' )
     , ( com/tag/5">5, 3, '9 Name Plaques' );


 SELECT  c.customer_name
      , COUNT(p.purchase_id) AS number_of_purchases
FROM    customer c
        LEFT JOIN purchases p
            ON c.customer_id = p.customer_id
GROUP BY c.customer_name
 

0 views   0 shares

profilepic.png
manpreet 2 years ago

COUNT(*) counts rows. You want to count matches, so count from the second table as following:

select customer.customer_name , a.number_of_purchases from (
SELECT customer_id, COUNT(purchases.purchase_id) AS number_of_purchaes 
FROM customer 
LEFT JOIN purchases ON customer.customer_id = purchases.customer_id 
GROUP BY customer.customer_id) as a 
inner join customer on customer.customer_id=a.customer_id;

In other words, the LEFT JOIN returns a row when there is no match. That row has a NULL value for all the columns in the purchases table.

 

0 views   0 shares

profilepic.png
manpreet 2 years ago
SELECT 
  com/tag/customer">customer_name, COUNT(purchase_id) AS number_of_purchases
FROM
  com/tag/customer">customer AS c
LEFT JOIN purchases AS p ON (c.cid = p.cid)
GROUP BY c.name

0 views   0 shares

profilepic.png
manpreet 2 years ago

Instead of count(*) use COUNT(purchases.customer_id)

SELECT customer_name, COUNT(purchases.customer_id) AS number_of_purchaes 
FROM customer 
LEFT JOIN purchases ON customer.customer_id = purchases.customer_id 
GROUP BY customer.customer_id

0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.