Calculated sum/count by category and sort descending, together with an inner join - sql

I have a simple table. One column with a variable which I want to sum or count and another one with category. I tried this:
SELECT COUNT(*) AS counted, category
FROM mytable
GROUP BY category
ORDER BY counted DESC;
With out the ORDER BY counted DESC it works, however it is not sorted. I would like to see the maximum immediately, so sort descending. However, when running it, a message pops up and asks me to insert a value for counted. Why can't I do this in one step, why is this not working?
Same for sum:
SELECT sum(variable) AS calcsum, category
FROM mytable
GROUP BY category
ORDER BY calcsum DESC;
Furthermore I have the same problem or similiar when trying to do this in one step with a join. I have one table with provided IDs (variable called keys). Another table with IDs, a category, a filter variable and a score. I want the sum of score per category and sort it descending. So far I have:
SELECT SUM(score) AS calcsum, category
FROM (
SELECT keys, category, filter, score INTO newdataset
FROM table1 INNER JOIN table2 ON table1.keys=table2.ID
WHERE table2.filter="Value")
GROUP BY category;
And I thought here again to add: ORDER BY calcsum DESC
However, even without adding the ORDER BY I get the error message "An action query cannot be used as a row source". So what is my mistake here?

Just repeat the COUNT(*) expression:
SELECT COUNT(*) AS counted, category
FROM mytable
GROUP BY category
ORDER BY COUNT(*) DESC;
EDIT:
If you want this with INTO and JOINs:
SELECT SUM(score) AS calcsum, category
INTO newdataset
FROM table1 INNER JOIN
table2
ON table1.keys =table2.ID
WHERE table2.filter = "Value"
GROUP BY category
ORDER BY SUM(score) DESC;

simply you can use order by 2 desc 2 stands for the second column in your select statement

Related

Why does adding GROUP BY cause a seemingly unrelated error?

The following code works fine:
SELECT name, (SELECT count(item_id) FROM bids WHERE item_id = items.id)
FROM items;
However, when I add
SELECT name, (SELECT count(item_id) FROM bids WHERE item_id = items.id)
FROM items
GROUP BY name;
I get ERROR: subquery uses ungrouped column "items.id" from outer query
Can anyone tell me why this is happening? Thanks!
If you GROUP BY name then any other columns you select from items must have an aggregate function applied. That's what GROUP BY means.
In your case, you are using another column from items -- id -- in a correlated scalar subquery. That's not an aggregate function, and id is not in the GROUP BY clause, so you get an error.
You could instead GROUP BY name, id. That should give you the same results as the first query, and is probably pointless.
If you actually have multiple rows in items with the same value for name, and you want to group the results of the scalar subquery for those values, you need to specify how to group them. Perhaps you want the total of the subquery results for each value of name. If so, I think you could do:
SELECT name, SUM(SELECT count(item_id) FROM bids WHERE item_id = items.id))
FROM items
GROUP BY name;
(I'm not positive about the specific syntax as I don't have a Postgres instance to test against.)
A clearer way to express it might be:
SELECT name, SUM(bid_count)
FROM (
SELECT name, (SELECT count(item_id) FROM bids WHERE item_id = items.id) AS bid_count
FROM items
)
GROUP BY name
Join the tables then perform the GROUP BY:
select i.name, count(b.item_id)
from items i
inner join bids b
on b.item_id = i.id
group by i.name
db<>fiddle here

How to Rank Based on Multiple Columns

I'm trying to score people in Microsoft Access based on the count they have for a particular category.
There are 7 possible categories a person can have against them, and I want to assigned each person a score from 1-7, with 1 being assigned to the highest scoring category, 7 being the lowest. They might not have an answer for every category, in which case that category can be ignored.
The aim would be to have an output result as shown in this image:
I've tried a few different things, including partition over and joins, but none have worked. To be honest I think I'm way off the mark with the queries I've been trying. I've tried to write the code in SQL from scratch, and used query builder.
Any help is really appreciated!
As you for an email can have duplicated counts, you will need two subqueries for this:
SELECT
Score.email,
Score.category,
Score.[Count],
(Select Count(*) From Score As T Where
T.email = Score.email And
T.[Count] >= Score.[Count])-
(Select Count(*) From Score As S Where
S.email = Score.email And
S.[Count] = Score.[Count] And
S.category > Score.category) AS Rank
FROM
Score
ORDER BY
Score.email,
Score.[Count] DESC,
Score.category;
For categories with equal Count values for the same email, the following will rank the records alphabetically descending by Category name (since this is what is shown in your example):
select t.email, t.category, t.count,
(
select count(*) from YourTable u
where t.email = u.email and
((t.count = u.count and t.category <= u.category) or t.count < u.count)
) as rank
from YourTable t
order by t.email, t.count desc, t.category desc
Change both references of YourTable to the name of your table.

How to use 'DISTINCT ON' to query last row of duplicate rows?

I came across this tutorial on DISTINCT ON () query. To achieve the output, the following query was used:
SELECT
DISTINCT ON
(bcolor) bcolor, fcolor
FROM
t1
ORDER BY
bcolor,
fcolor;
The
is illustrated here where the top row of the duplicated rows are returned. However, is there a way to return the bottom of the duplicated rows instead? My use case is that multiple applications/registrations might enter and I want to query all the most recent distinct applications.
Appreciate your time, cheers!
I think you just want a descending sort on the second key:
SELECT DISTINCT ON (bcolor) bcolor, fcolor
FROM t1
ORDER BY bcolor, fcolor DESC;
Assuming you have a date or id columns that increments to indicate what the most recent row is, simply order by that column and add DESC to specify ordering by descending order.
SELECT
DISTINCT ON
registration_date, student_id, student_name
FROM
t1
ORDER BY
registration_date desc,
student_id,
student_name;

Get the first instance of a row using MS Access

EDITED:
I have this query wherein I want to SELECT the first instance of a record from the table petTable.
SELECT id,
pet_ID,
FIRST(petName),
First(Description)
FROM petTable
GROUP BY pet_ID;
The problem is I have huge number of records and this query is too slow. I discovered that GROUP BY slows down the query. Do you have any idea that could make this query faster? or better, a query wherein I don't need to use GROUP BY?
"The problem is I have huge number of records and this query is too slow. I discovered that GROUP BY slows down the query. Do you have any idea that could make this query faster?"
And an index on pet_ID, then create and test this query:
SELECT pet_ID, Min(id) AS MinOfid
FROM petTable
GROUP BY pet_ID;
Once you have that query working, you can join it back to the original table --- then it will select only the original rows which match based on id and you can retrieve the other fields you want from those matching rows.
SELECT pt.id, pt.pet_ID, pt.petName, pt.Description
FROM
petTable AS pt
INNER JOIN
(
SELECT pet_ID, Min(id) AS MinOfid
FROM petTable
GROUP BY pet_ID
) AS sub
ON pt.id = sub.MinOfid;
Your Query could change as,
SELECT ID, pet_ID, petName, Description
FROM petTable
WHERE ID IN
(SELECT Min(ID) As MinID FROM petTable GROUP BY pet_ID);
Or use the TOP clause,
SELECT petTable.petID, petTable.petName, petTable.[description]
FROM petTable
WHERE petTable.ID IN
(SELECT TOP 1 ID
FROM petTable AS tmpTbl
WHERE tmpTbl.petID = petTable.petID
ORDER BY tmpTbl.petID DESC)
ORDER BY petTable.petID, petTable.petName, petTable.[description];

Sort by count SQL reporting services

I have a simple query in a tabloid control that gets all the leads in one month. I then use the tabloid control to group them into lead source. And then I have an associated count column. I want to sort my report on the count descending, without doing it in the query. I keep getting an error saying you cannot sort on an aggregate.
Thanks.
you can do one more thing..
just write your query in subquery part and write order by clause in outer query.
(suppose you have group by query as follow-
select lead_source, count(*) cnt
from your_table
group by lead_source
)
so you can do as follow -
select lead_source, cnt from (
select lead_source, count(*) cnt
from your_table
group by lead_source
)
order by cnt
this your_table and group by column list you have to edit accordingly your table structure ..