Group By with count doesn't work - sql

I am trying to use group by with count function but this doesn't work.
SELECT
projects.AgencyId,
projects.ProgramId,
count(projects.ProjStatusByMin) as status,
projects.ProjStatusByMin
from
projects
where
projects.AgencyId=40
group by
projects.ProjStatusByMin
This above code works in MySQL perfectly now i want to achieve the same thing in SQL Server.
Select
ProjStatusByMin,
COUNT(ProjStatusByMin) [projstatus]
from
Projects
where
AgencyId=40
group by
ProjStatusByMin,AgencyId,ProjId
However if i select a single column like the bellow code then group by work
Select
ProjStatusByMin,
COUNT(ProjStatusByMin) [projstatus]
from
Projects
where
AgencyId=40
group by
ProjStatusByMin
Now how can I achieve group by with multi column selected?

You have to add all the columns (except for the one in the count function) to the group by clause.
SELECT projects.AgencyId,projects.ProgramId,count(projects.ProjStatusByMin) as status,
projects.ProjStatusByMin
from projects
where projects.AgencyId=40
group by projects.ProjStatusByMin, projects.AgencyId,projects.ProgramId

In Sql Server you have to write all the column names in group by clause which you are going to select in the select statement.

Related

Filter SQL by Aggregate Not in SELECT Statement

Can you filter a SQL table based on an aggregated value, but still show column values that weren't in the aggregate statement?
My table has only 3 columns: "Composer_Tune", "_Year", and "_Rank".
I want to use SQL to find which "Composer_Tune" values are repeated in each annual list, as well as which ranks the duplicated items had.
Since I am grouping by "Composer_Tune" & "Year", I can't list "_Rank" with my current code.
The image shows the results of my original "find the duplicates" query vs what I want:
Current vs Desired Results
I tried applying the concepts in this Aggregate Subquery StackOverflow post but am still getting "_Rank is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause" from this code:
WITH DUPE_DB AS (SELECT * FROM DB.dbo.[NAME] GROUP BY Composer_Tune, _Year HAVING COUNT(*)>1)
SELECT Composer_Tune, _Year, _Rank
FROM DUPE_DB
You need to explicitly declare the columns used in the Group By expression in the select columns.
You can use the following documentation if you are using transact sql for the proper use of Group By.
Simply join the aggregated resultset to original unit level table:
WITH DUPE_DB AS (
SELECT Composer_Tune, _Year
FROM DB.dbo.[NAME]
GROUP BY Composer_Tune, _Year
HAVING COUNT(*) > 1
)
SELECT n.Composer_Tune, n._Year, n._Rank
FROM DB.dbo.[NAME] n
INNER JOIN DUPE_DB
ON n.Compuser_Tune = DUPE_DB.Composer_Tune
AND n._Year = DUPE_DB._Year
ORDER n.Composer_Tune, n._Year

How to extract duplicate orders from DB

Using SQL Server 2014. Taking the following recordset:
I need to find a way to extract the ordOrderNum which is duplicates, with a different DeliveryNum. In this example, orders 93400460 and 93400467 would be extract, because they are duplicates. Order 93408170 is ok. How can I do that??!
thanks for your time and help
You can use group by and having:
select ordOrderNum
from mytable
group by ordOrderNum
having min(ordDeliveryNum) <> max(ordDeliveryNum)
Try this:
SELECT
ORDORDERNUM, ORDLINENUM,
COUNT(*) FROM TABLE
GROUP BY
ORDORDERNUM, ORDLINENUM
Having count(*)>1

Why isn't this simple SQL query working? select *, count(*) from table

I'm trying to learn SQL and am following along with an exercise, but I am hung up on why this simple SQL statement will not work.
select *, count(*) from bricks
What the instructor is trying to do is return all the rows of a table named bricks. We also want to append a new column to the right side of the table that simply returns the total count of all bricks in each record. So there are 6 bricks total in the table, so each row should have a column at the end that just reads 6.
The way that the instructor did it is by doing this:
select b.*, (select count(*) from bricks) total_bricks_in_table from bricks b;
The first query is my attempt at it and I don't see why it doesn't work seeing as running
select * from bricks
and
select count(*) from bricks
Each work on their own, but not when combined. I've tried adding a group by statement to the end of my attempt but no matter which column I group by I still get errors. What exactly is wrong with my original attempt?
It is because COUNT is an aggregate function, and once you use one aggregate, you have to choose how to aggregate every other columns of your SELECT statement.
This query:
select *, count(*)
from bricks
is malformed. Because of the count() this is an aggregation query. An aggregation query with no group by always returns one row. However, you are also trying to select other columns -- any reasonable database will follow the SQL standard and return an error.
What can you do? SQL has something called window functions. This makes it quite simple to do what you want:
select *, count(*) over () as num_bricks
from bricks

pgSQL query error

i tried using this query:
"SELECT * FROM guests WHERE event_id=".$id." GROUP BY member_id;"
and I'm getting this error:
ERROR: column "guests.id" must appear in the GROUP BY clause or be used in an aggregate function
can anyone explain how i can work around this?
You can't Group By without letting the Select know what to take, and how to group.
Try
SELECT guests.member_id FROM guests WHERE event_id=".$id." GROUP BY member_id;
IF you need to get more info from this table about the guests, you'll need to add it to the Group By.
Plus, it seems like your select should actually be
SELECT guests.id FROM guests WHERE event_id=".$id." GROUP BY id;
Each of the columns used in a group by query needs to be specifically called out (ie, don't do SELECT * FROM ...), as you need to use them in some sort of aggregate function (min/max/sum/avg/count/etc) or be part of the group by clause.
For example:
SELECT instrument, detector, min(date_obs), max(date_obs)
FROM observations
WHERE observatory='SOHO'
GROUP BY instrument, detector;

Can I group by something that isn't in the SELECT line?

Given a command in SQL;
SELECT ...
FROM ...
GROUP BY ...
Can I group by something that isn't in the SELECT line?
Yes.
This is often used in the superaggregate queries like this:
SELECT AVG(cnt)
FROM (
SELECT COUNT(*) AS cnt
FROM sales
GROUP BY
product
HAVING COUNT(*) > 10
) q
, which aggregate the aggregates.
Yes of course e.g.
select
count(*)
from
some_table_with_updated_column
group by
trunc(updated, 'MM.YYYY')
Yes you can do it, but if you do that you won't be able to tell which result is for which group.
As a result, you almost always want to return the columns you've grouped by in the select clause. But you don't have to.
Yes, you can. Example:
select count(1)
from sales
group by salesman_id
What you can't do, of course, if having something on your select clause (other than aggregate functions) that are not part of the group by clause.
Hmm, I think the question should have been in the other way round like,
Can I SELECT something that is not there in the GROUP BY?
It's alright to write a code like:
SELECT customerId, count(orderId) FROM orders
GROUP BY customerId, orderedOn
If you want to find out the number of orders done by a customer datewise.
But you cannot do it the other way round:
SELECT customerId, orderedOn count(orderId) FROM orders
GROUP BY customerId
You can issue an aggregate function on the column that is not there in the group by. But you cannot give it in the select line without the aggregate function. As it will not make much sense. Like for the above query. You group by just customerId for order counts and you want the date also to be printed in the output??!! You don't involve the date factor in the group for counting then will it mean something to have a date in it?
I don't know about other DBMS' but DB2/z, for one, does this just fine. It's not required to have the column in the select portion but, of course, it does have to extract the data from the table in order to aggregate so you're probably not saving any time by leaving it off. You should only select the columns that you need, aggregation of the data is a separate task from that.
I'm pretty certain the SQL standard allows this (although that's only based on the knowledge that the mainframe DB2 product follows it pretty closely).