group by subquery in sql server - 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.

Related

SQL queries combined into one row

I'm having some difficulty combining the following queries, so that the results display in one row rather than in multiple rows:
SELECT value FROM dbo.parameter WHERE name='xxxxx.name'
SELECT dbo.contest.name AS Event_Name
FROM contest
INNER JOIN open_box on open_box.contest_id = contest.id
GROUP BY dbo.contest.name
SELECT COUNT(*) FROM open_option AS total_people
SELECT SUM(scanned) AS TotalScanned,SUM(number) AS Totalnumber
FROM dbo.open_box
GROUP BY contest_id
SELECT COUNT(*) FROM open AS reff
WHERE refer = 'True'
I would like to display data from the fields in each column similar to what is shown in the image below. Any help is appreciated!
Tab's solution is fine, I just wanted to show an alternative way of doing this. The following statement uses subqueries to get the information in one row:
SELECT
[xxxx.name]=(SELECT value FROM dbo.parameter WHERE name='xxxxx.name'),
[Event Name]=(SELECT dbo.contest.name
FROM contest
INNER JOIN open_box on open_box.contest_id = contest.id
GROUP BY dbo.contest.name),
[Total People]=(SELECT COUNT(*) FROM open_option),
[Total Scanned]=(SELECT SUM(scanned)
FROM dbo.open_box
GROUP BY contest_id),
[Total Number]=(SELECT SUM(number)
FROM dbo.open_box
GROUP BY contest_id),
Ref=(SELECT COUNT(*) FROM open WHERE refer = 'True');
This requires the Total Scanned and Total Number to be queried seperately.
Update: if you then want to INSERT that into another table there are essentially two ways to do that.
Create the table directly from the SELECT statement:
SELECT
-- the fields from the first query
INTO
[database_name].[schema_name].[new_table_name]; -- creates table new_table_name
Insert into a table that already exists from the INSERT
INSERT INTO [database_name].[schema_name].[existing_table_name](
-- the fields in the existing_table_name
)
SELECT
-- the fields from the first query
Just CROSS JOIN the five queries as derived tables:
SELECT * FROM (
Query1
) AS q1
CROSS JOIN (
Query2
) AS q2
CROSS JOIN (...
Assuming that each of your individual queries only returns one row, then this CROSS JOIN should result in only one row.

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.

Select distinct with join and group by

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.

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