Select distinct with join and group by - sql-server

I'm trying to run the query:
Select Distinct table2.columnA columnA_0 ,
table3.columnB columnB_1 ,
table2.columnC columnC_2
From table4 Join table1 on table4.columnD = table1.columnD
Left Outer Join table2 on table2.columnD = table1.columnD
Left Outer Join table3 on table3.columnE = table2.columnE
where table2.columnA IS NOT NULL
group by dbo.table2.columnA
but I am receiving the error
Column 'table3.columnB' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
Can anyone tell me why?

The WHY is that all columns in the select portion of your query (table2.columnA columnA_0, table3.columnB columnB_1, table2.columnC columnC_2) must be included in the GROUP BY clause, OR be used in an aggregate function like SUM, MIN, MAX, etc.

This would be because you are explicitly grouping by table2.columnA, yet some of the values in the select clause are neither aggregated nor grouped. Since you want distinct values (based on your inclusion of the distinct keyword), simply remove the group by clause.
If you have previously used MySQL, this may be new to you - MySQL allows the inclusion of unaggregated, ungrouped columns in the select clause of a grouped query; most other RDBMSs do not.

Related

Aggregate may not appear in WHERE clause even if i dont have condition while using SUM

I have this below query
SELECT A.*,SUM(ISNULL(B.DEPTRAN_DEPOSIT,0)-ISNULL(B.DEPTRAN_WITHDRAWAL,0)) as BALANCE
FROM DEPOSITFDMASTER A
INNER JOIN DEPOSITTRANSACTION B ON A.DEPSUBTYPE_ID=B.DEPSUBTYPE_ID AND A.FD_ID=B.DEPOSIT_DATAID WHERE SUM(ISNULL(B.DEPTRAN_DEPOSIT,0)-ISNULL(B.DEPTRAN_WITHDRAWAL,0))>10
when i try to execute i will get the below error. If i remove where condtion then the query will work properly.
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
P.S:DEPTRAN_DEPOSIT and DEPTRAN_WITHDRAWAL both having DataType Decimal(18,2).
Any help appreciated.
I'd suggest you use GROUP BY and HAVING. Something like this
SELECT
A.*
,SUM(ISNULL(B.DEPTRAN_DEPOSIT,0)-ISNULL(B.DEPTRAN_WITHDRAWAL,0)) as BALANCE
FROM DEPOSITFDMASTER A
INNER JOIN DEPOSITTRANSACTION B
ON
A.DEPSUBTYPE_ID=B.DEPSUBTYPE_ID
AND
A.FD_ID=B.DEPOSIT_DATAID
GROUP BY [All columns in A] --like that A.Column1,A.COlumn2,....,A.ColumnN
HAVING SUM(ISNULL(B.DEPTRAN_DEPOSIT,0)-ISNULL(B.DEPTRAN_WITHDRAWAL,0))>10

ms access GROUP BY error

I'm trying to run this SQL in MS access
SELECT `orig`.`SONG TITLE`,`orig`.`PUBLISHER`,`orig`.`CFG DESCRIPTION`
FROM `Sheet1` AS `orig`
INNER JOIN `Sale type` AS `Sale`
ON orig.`CFG DESCRIPTION`=Sale.`CFG DESC`
GROUP BY orig.`SONG TITLE` , orig.`PUBLISHER`
;
I get an error saying: "Your query does not include the specified expression 'CFG DESCRIPTION' as a part of an aggregate function"
When I run this query without the GROUP BY clause all works fine. What am I doing wrong with the GROUP BY??
The group by clause means that you get one result row per distinct combination of the grouped columns. This means your select list can only contains columns that are grouped by, or aggregate functions (e.g., count, sum, min, max, etc.)
So you should either add CFG DESCRIPTION to the group by clause:
SELECT `orig`.`SONG TITLE`,`orig`.`PUBLISHER`,`orig`.`CFG DESCRIPTION`
FROM `Sheet1` AS `orig`
INNER JOIN `Sale type` AS `Sale`
ON orig.`CFG DESCRIPTION`=Sale.`CFG DESC`
GROUP BY orig.`SONG TITLE` , orig.`PUBLISHER`,`orig`.`CFG DESCRIPTION`
;
Or remove it from the select list:
SELECT `orig`.`SONG TITLE`,`orig`.`PUBLISHER`
FROM `Sheet1` AS `orig`
INNER JOIN `Sale type` AS `Sale`
ON orig.`CFG DESCRIPTION`=Sale.`CFG DESC`
GROUP BY orig.`SONG TITLE` , orig.`PUBLISHER`
;
Depending on the result you need, of course.
GROUP BY is an all-or-nothing concept, where every column you select needs to be in the clause unless it's an aggregate. Include orig.CFG DESCRIPTION at the end of the GROUP BY and it should run.
I think you need to add orig.[GFC DESCRIPTION] to your Group By:
GROUP BY orig.[SONG TITLE] , orig.[PUBLISHER], orig.[GFC DESCRIPTION]
If that does not work for your situation, place the orig.[GFC DESCRIPTION] in an aggregate function:
SELECT orig.SONG TITLE,orig.PUBLISHER,MIN(orig.CFG DESCRIPTION)
FROM Sheet1 AS orig
INNER JOIN Sale type AS Sale
ON orig.CFG DESCRIPTION=Sale.CFG DESC
GROUP BY orig.SONG TITLE , orig.PUBLISHER
;
You can use any aggregate function, such as MAX, FIRST (Access Specific), etc.

group by subquery in sql server

I have a table and want to group the records by dynamically generated column. Say as in my query it is newcol. On executing this query i am receiving the error:
Column 'SalesProductDetails.ProductId' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
This is query i have tried
select tbl.nwecol,tbl.ProductId,tbl.Products_Name,tbl.Qunatity,tbl.SKUCode
from (
select SPD.ProductID,
PR.SKUCode,
PR.Products_Name,
sum(SPD.Qunatity) as Qunatity,
cast(round(((SPD.BasePrice*SPD.Qunatity)+STD.SalesTaxAmt)/SPD.Qunatity,2) as numeric(36,2)) as nwecol,
SM.Isactive
from SalesProductDetails SPD
join SalesMaster SM
on SPD.SalesId=SM.SalesId
join Sales_TaxDetails STD
on SPD.ProductSalesID=STD.ProductSalesID
join Products Pr
on Pr.ProductID=SPD.ProductId
where SPD.Isactive=1
and SM.Isactive=1
and SPD.ProductId=1
) as tbl
group by tbl.nwecol,tbl.ProductId,tbl.Products_Name,tbl.Qunatity,tbl.SKUCode
I think what you're trying to do is calculate the sum based on the column you generated (nwecol). In that case, you need to move the aggregate (SUM) outside of the subquery like so:
select tbl.nwecol,tbl.ProductId,tbl.Products_Name,tbl.SKUCode,
SUM(tbl.Qunatity)
from (
select SPD.ProductID,
PR.SKUCode,
PR.Products_Name,
SPD.Qunatity
cast(round(((SPD.BasePrice*SPD.Qunatity)+STD.SalesTaxAmt)/SPD.Qunatity,2) as numeric(36,2)) as nwecol,
SM.Isactive
from SalesProductDetails SPD
join SalesMaster SM
on SPD.SalesId=SM.SalesId
join Sales_TaxDetails STD
on SPD.ProductSalesID=STD.ProductSalesID
join Products Pr
on Pr.ProductID=SPD.ProductId
where SPD.Isactive=1
and SM.Isactive=1
and SPD.ProductId=1
) as tbl
group by tbl.nwecol,tbl.ProductId,tbl.Products_Name,tbl.SKUCode
I think it is need not to use group by clause without using any aggregate function like (sum,avg,count,max) . Let's try without group by clause in outer select statement
you have used product_id for Product_details As PR table in the join but missed to write the same in the group by clause!!!!
I'm not sure what is unclear about the error message. Your aggregation is on the following columns:
tbl.nwecol
tbl.ProductId
tbl.Products_Name
tbl.Qunatity
tbl.SKUCode
None of these are tbl.ProductId. So, you can solve this by wrapping the latter in an aggregation function, such as:
MIN(tbl.ProductId)
MAX(tbl.ProductId)
Or, include tbl.ProductId in the group by.

SQL FROM clause using n>1 tables

If you add more than one table to the FROM clause (in a query), how does this impact the result set? Does it first select from the first table then from the second and then create a union (i.e., only the rowspace is impacted?) or does it actually do something like a join (i.e., extend the column space)? And when you use multiple tables in the FROM clause, does the WHERE clause filter both sub-result-sets?
Specifying two tables in your FROM clause will execute a JOIN. You can then use the WHERE clause to specify your JOIN conditions. If you fail to do this, you will end-up with a Cartesian product (every row in the first table indiscriminately joined to every row in the second).
The code will look something like this:
SELECT a.*, b.*
FROM table1 a, table2 b
WHERE a.id = b.id
However, I always try to explicitly specify my JOINs (with JOIN and ON keywords). That makes it abundantly clear (for the next developer) as to what you're trying to do. Here's the same JOIN, but explicitly specified:
SELECT a.*, b.*
FROM table1 a
INNER JOIN table2 b ON b.id = a.id
Note that now I don't need a WHERE clause. This method also helps you avoid generating an inadvertent Cartesian product (if you happen to forget your WHERE clause), because the ON is specified explicitly.

Getting Columns Related to GROUP BY Column

I'd like to do something like the following.
SELECT aspnet_Users.UserName, aspnet_Membership.Email, count(*) as Activities
FROM aspnet_Users
INNER JOIN Activities ON aspnet_Users.UserId = Activities.ActUserID
INNER JOIN aspnet_Membership ON aspnet_Users.UserId = aspnet_Membership.UserId
WHERE Activities.ActDateTime >= GETDATE()
GROUP BY aspnet_Users.UserName
ORDER BY Activities DESC
But this gives me an error.
Column 'aspnet_Membership.Email' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I understand the error somewhat. I'm trying to select a column that is not part of the grouping.
However, there will always be a one-to-one relationship between aspnet_Membership.Email and aspnet_Users.UserId. So how would I implement this?
Change:
GROUP BY aspnet_Users.UserId
To:
GROUP BY aspnet_Users.UserName, aspnet_Membership.Email
Not sure why you think you need to mention the UserId column in the grouping if you don't want to return it, or why you think you shouldn't group by the columns you do want to return.
to select a column it must either be in a group by clause or aggregated ,you could consider grouping by (aspnet_Users.UserName, aspnet_Membership.Email,aspnet_Users.UserId ) .
my guess is it would work

Resources