1

I want to ask how do I select data together with count data.

In this case, I want the user to appear and the number of transactions that he has.

Like this code that I made.

SELECT "transaction"."user_id",
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY user_id

The code above successfully selects user_id and trans_count, but when I am trying to show users.name

this error message appears.

Error in query: ERROR: column "users.name" must appear in the GROUP BY clause or be used in an aggregate function LINE 3: "users"."name"

Is it true that I am cannot select other data when I count data or is there a better way ?.

Thank You.

3
  • When several tables are involved, it's good programming practice to qualify all columns, like "transaction"."user_id". Commented Jan 22, 2020 at 8:49
  • 1
    You typically GROUP BY the same columns as you SELECT, except those who are arguments to set functions. Commented Jan 22, 2020 at 8:49
  • I don't think there is a need for group by to call others. Thank you very helpful Commented Jan 22, 2020 at 8:55

3 Answers 3

2

You can include user.name in the group by:

SELECT "transaction"."user_id",
"user"."name",
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY "transaction"."user_id", "user"."name"

Otherwise, when the DBMS tries to combine (group) multiple rows into a single row, it doesn't know which name value should it pick, which is why it throws the error.

In this case, user_id and user.name have a one-to-one mapping, so you can simply include name in the group by clause.

Otherwise you'd have to tell the DBMS how to select one value from the multiple records that are in each group, eg:

min(user.name) or max(user.name)

SELECT "transaction"."user_id",
min("user"."name") user_name,
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY "transaction"."user_id"
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the explanation now I am understand, this works now !. :)
0

When every your using GROUP BY You must be group by all column which is fetching or use Aggregate Functions

Group by (same as @rohitvats)

GROUP BY "transaction"."user_id", "user"."name"

---- OR ----

Aggregate Functions MAX(), MIN()

SELECT "transaction"."user_id",
MAX("user"."name") as name,
COUNT(transaction.id) trans_count
FROM transaction 
inner join "users" on "users"."id" = "transaction"."user_id"
GROUP BY "transaction"."user_id"

1 Comment

This is very helpful, after this i will learn more about the function you mean.
0

Your code would work if you aggregated by the users.id:

SELECT u.id, u.user_name, COUNT(*) as trans_count
FROM users u JOIN
     transaction t
     ON t.id = u.user_id
GROUP BY u.id;

(I removed the double quotes because they clutter the logic and are not necessary to explain what is going on.)

Why? Presumably, users.id is unique (or equivalently the primary key). Postgres supports aggregating by a unique key in a table and also including unaggregated columns in the SELECT. This is an implementation of "functional dependent" aggregations from the SQL standard.

When you use transactions.user_id, Postgres does not recognize the functional dependence (even though you might think that the ON clause would imply it). So, your code doesn't work.

The alternative is to add user_name to the GROUP BY as well. However, your version almost works if you use the column from the correct table.

1 Comment

So like that. Thank you for your explanation is very easy to understand. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.