Search code examples
sqlpostgresqlgroup-byleft-joinhaving-clause

Postgresql get List all customer who has 3 or more record transaction


Iam Using postgreSQL. I have 2 table with relations

table customer:

-------------------------------------------
| customer_id (PK) | first_name | last_name  |
-------------------------------------------
| 1                | ogi        |    tampoo  |
| 2                | cimol      |    comet   |
| 3                | cocang     |    tampoo  |
| 4                | bedu       |    comet   |
| 5                | bonjof     |    tampoo  |

table transaction:

---------------------------------------------------------
| transaction_id (PK) | customer_id (FK) | total_value  |
---------------------------------------------------------
| 2                   |      1           |    250500    |
| 5                   |      2           |    340600    |
| 4                   |      3           |    150800    |
| 6                   |      4           |     90900    |
| 3                   |      4           |    1009000   |
| 1                   |      5           |    540700    |
| 7                   |      4           |    340000    |

question:

Return all customer who has >1 record transaction.
Obviously from transaction table, customer_id = 4 have 3 records
how to  query this?

Desired result

--------------------------------------------------------------------------------------
| customer_id | first_name | last_name  | transaction_id | customer_id  | total_value |
--------------------------------------------------------------------------------------
| 4           | bedu       |    comet   |       5        |      4       |      90900  |
| 4           | bedu       |    comet   |       3        |      4       |     1009000 |
| 4           | bedu       |    comet   |       7        |      4       |     340000  |

what I've try :

  1. (return nothing)
select cs.* ,tr.*
from 
    customer cs
left join
    transaction tr
    on tr.customer_id = cs.customer_id
group by cs.customer_id , tr.transaction_id
having count(cs.customer_id)>1

  1. ERROR: column "cs.customer_id" must appear in the GROUP BY clause or be used in an aggregate function
    ERROR: column "tr.transaction_id" must appear in the GROUP BY clause or be used in an aggregate function
select *
from 
     customer  cs
left join 
     transaction tr
     on tr.customer_id = cs.customer_id
group by tr.customer_id
having count(tr.customer_id)>1

It appear that (i dont know if it only postgres), It forced to group by each PRIMARY KEY.
When I try to group by any other column which is not PK, it return error and demand the PK for group by.

Thank you very much.


Solution

  • Your last query almost works. Just select the columns from the customer table -- and join by the primary key:

    select c.*
    from customer c join 
         transaction t
         on t.customer_id = c.customer_id
    group by c.customer_id
    having count(*) > 1
    

    If you want any columns from t, then you need to use an aggregation function. For instance COUNT(*) to count the number of transactions.

    Also note that I changed the LEFT JOIN to an INNER JOIN. You require a match in order to meet the HAVING condition, so the outer join is not needed.