Column in aggregate function but sqlserver says it isn't - sql-server-2000

I tried to run the following query:
select a,b,min(c) from tablename where e=1 and f=1 group by a,b order by a,b,c
But got the error:
Column name 'tablename.c' is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.
However c is contained in the aggregate function min(), so what's the issue here? Is there a workaround?
This is on sqlserver 2000 (using the sqlserver 2008 management console).

As you are using the aggregation on that column, is no longer c but "aggregated c" that is why you can not use it in the order by clause.
You need to alias that column to use it in order by
select a,b,min(c) as min_c from tablename where e=1 and f=1 group by a,b order by a,b,min_c
EDIT:
Why the column c is not available ?
While in the statement we use clause group by, our original table i transformed into new temporary one.
In your case you used the column a and b to group, the the data in those column will not be changed only limited to unique.
On the column c you are using a function that for each unique group will retrieve the lowest value of c, for this purpose a new column has to be created that will store that results.
The order by clause is the last part of query that is executed over the select section. So over the result of the temporary table not the source one.
The simply order of statement execution goes like this:
FORM
JOIN
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

try this
select * from
(
select a,b,min(c) as c from tablename where e=1 and f=1 group by a,b
) d order by a,b,c

try this:
select a,b,min(c)
from tablename
where e=1 and f=1
group by a,b
order by a,b,min(c)
or this:
select a,b,min(c)
from tablename
where e=1 and f=1
group by a,b
order by 1,2,3

Related

SQL Server, include columns that are not in group by statement

I have a permanent problem,
lets assume that I have a following columns:
T:A(PK), B, C, D, E
Now,
select A, MAX(B) from T group BY A
No, I cant do:
select A, C, MAX(B) from T group BY A
I don't understand why - when in comes to AVG or SUM I get it. However, MAX or MIN is getting from exactly one row.
How to deal with it?
You can use ROW_NUMBER() for that like this:
select A, C, B
from (
select *
, row_number() over (partition by A order by B desc) seq
-- group by ^ max(^)
from yourTable ) t
where seq = 1;
That's cause columns included in the select list should also be part of group by clause. You may have column which re part of group by but not present in select list but vice-versa not possible.
You generally, put only those columns in select clause on which you want the grouping to happen.
try this. it can help you find the MAX by just 1 column (f1), and also adding the column you wanted(f3) but not affecting your MAX operation
SELECT m.f1,s.f2,m.maxf3 FROM
(SELECT f1,max(f3) maxf3 FROM t1 GROUP BY f1) m
CROSS APPLY (SELECT TOP(1) f2,f1 FROM t1 WHERE m.f1 = f1) s
Your question isn't very clear in that we aren't sure what you are trying to do.
Assuming you don't actually want to do a group by in your main query but want to return the max of B based on column A you can do it like so.
select A, C,(Select Max(B) from T as T2 WHERE T.A = T2.A) as MaxB from T

Remove a column after selection with SQL

I want my result set to include only one column, but I'm using a different column to group by and order by.
Can I somehow, after selecting and order by removing the column from the result set?
Using MSSQL2008
Just add another SELECT around your query, like so:
SELECT
sum_columnB
FROM
(SELECT
columnA
, SUM(columB) sum_columnB
FROM Table
GROUP BY columnA
ORDER BY columnA
, sum_columnB) resultset
But if you would post your query, my answer could be more specific and maybe clearer.
You do not have to select all the columns your order or group by, you can just select the column you want.
SELECT A
FROM dbo.Table
GROUP BY A,B
ORDER BY A,B

How to apply Count on multiple distinct columns and use Having clause

I would like to do something like this , but getting an error please suggest some good methods?
select A,B,C, count(Distinct A,B,C)
from table_name
group by A,B,C
having count(Distinct A,B,C) > 1
Basically i have an index on the columns(A,B,C), and some rows doesnt have this unique combination set, So I'm trying a query similar to identify the rows which disobeys the unique constraint. PLease let me know if there is a best way
If you group by these columns then you already only get those unique records and then you can use count(*) to get how many duplicates you have
select A,B,C, count(*)
from table_name
group by A,B,C
HAVING count(*) > 1
What #jurgend said is right, and you can further find the exact rows (I'm assuming there are more fields to look at, including maybe a PK) by doing
SELECT *
FROM table_name
WHERE (A,B,C) IN (
SELECT A, B, C
FROM table_name
GROUP BY A, B, C
HAVING COUNT(*) > 1
)
A Tuple IN list query works in Oracle, although not all other DBMS.

Group Count in SQL

I am looking for a way to display a table where a set of multiple attributes appear more than one time.
For example, suppose I had a table, Tbl1 with attributes A, B, C, D, E
How do I make a query such that it only shows rows where A, B, C appear more than once (as in the same A, B, C as a group), but D and E may or may not be different?
My attempt:
SELECT *
FROM Tbl1
WHERE COUNT(A, B, C) > 1
and I get an error: "group function is not allowed here"
The reason for this is, that you cannot use this grouping in the WHERE-part of an sql clause.
SELECT colums
FROM tables
WHERE condition
the condition refers to a single row of the table.
What you want is HAVING
SELECT colums
FROM tables
HAVING condition
The condition after HAVING is evaluated after the grouping and there you can use aggregation functions like COUNT or SUM
Use the GROUP BY clause (SQL Server: http://msdn.microsoft.com/en-us/library/ms177673.aspx, MySQL: http://www.tutorialspoint.com/mysql/mysql-group-by-clause.htm).
Within each group, you'll want to get get the count of rows in that group (using COUNT(*)) and then use a HAVING clause to filter on that count. HAVING is like a WHERE clause for GROUP BY. It filters on the results of the grouping, and can make reference to the grouped columns (in this case, A, B and C), or any aggregates (in this case, COUNT(*)).
Here's what your query could look like. Note that you can only include columns in the SELECT field list that are mentioned in the GROUP BY or that are contained in aggregate functions such as COUNT() and MAX(). MySQL will let you get away with putting other columns in, but SQL Server will give you an error. It's best to follow this rule even if the database allows it.
SELECT A,
B,
C,
COUNT(*) AS GroupCount
FROM Tbl1
GROUP BY A, B, C
HAVING COUNT(*) > 1
If you want the full rows where this is true, then you can used a derived table:
SELECT *
FROM Tbl1
JOIN (
SELECT A,
B,
C,
COUNT(*) AS GroupCount
FROM Tbl1
GROUP BY A, B, C
HAVING COUNT(*) > 1
) AS duplicates
ON duplicates.A = Tbl1.A AND
duplicates.B = Tbl1.B AND
duplicates.C = Tbl1.C

How can I use the GROUP BY SQL clause with no aggregate function?

When I try to use the following SELECT statement:
SELECT [lots of columns]
FROM Client, Customer, Document, Group
WHERE [some conditions]
GROUP BY Group.id
SQL Server complains that the columns I selected are not part of the GROUP BY statement nor an aggregate function. Am I using GROUP BY wrong? What should I be using instead?
To return all single occurences of a group by field, together with associated field values, write a query like:
select group_field,
max(other_field1),
max(other_field2),
...
from mytable1
join mytable2 on ...
group by group_field
having count(*) = 1;
Yes, you are using GROUP BY incorrectly. The point of using GROUP BY is to use aggregate functions. If you have no aggregrate functions you probably want SELECT DISTINCT instead.
SELECT DISTINCT
col1,
col2,
-- etc
coln
FROM Client
JOIN Customer ON ...
JOIN Document ON ...
JOIN [Group] ON ...
WHERE ...
My first guess would be that the problem is that you have table called Group, which I believe is a reserved word in SQL. Try wrapping the Group name with ' '
You want to group by all columns you are selecting that is not in an aggregate funcion.
SELECT ProductName, ProductCategory, SUM(ProductAmount)
FROM Products
GROUP BY ProductName, ProductCategory
This will give you a disticnt result of Product names and categories with the sum total of product amount in all aggregate child records for that group.