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.
Related
I am developing a report against a SQL Server database. Using the query presented here...
SELECT
f.FacilityID as 'FID',
COUNT (DISTINCT f.PhoneTypeID) as 'Ptypes',
COUNT (DISTINCT f.PhoneID) as 'Pnumbers'
from dbo.FacilityPhones as f
inner join
dbo.Phones as ph
f.PhoneID = ph.PhoneID
group by f.FacilityID
having COUNT(DISTINCT f.PhoneTypeID)<>COUNT(DISTINCT f.PhoneId);
...I have identified 107 records where the number of phone numbers present for a Facility differs from the number of phone number types (e.g., there are two distinct phone numbers, both listed as primary).
I would like to be able to produce a detailed report that would list phone numbers and phone types for each facility, but ONLY when the distinct counts differ.
Is there a way to do this with a single query? Or would I need to save the summaries to a temp table, then join back to that temp table to get the details?
Not sure what fields exist in dbo.Phone; but assume the number comes from there... Likely need to join to the type table to get it's description as well...
This uses a common table expression to get your base list of items an then a correlated subquery to ensure only those facilities in your cte are displayed.
WITH CTE AS (
SELECT f.FacilityID as 'FID'
, COUNT (DISTINCT f.PhoneTypeID) as 'Ptypes'
, COUNT (DISTINCT f.PhoneID) as 'Pnumbers'
FROM dbo.FacilityPhones as f
GROUP BY f.FacilityID
HAVING COUNT(DISTINCT f.PhoneTypeID)<>COUNT(DISTINCT f.PhoneId))
SELECT *
FROM dbo.FaclityPhones FP
INNER JOIN dbo.Phones as ph
ON FP.PhoneID = ph.PhoneID
WHERE EXISTS (SELECT 1
FROM CTE
WHERE FID = FP.FacilityID)
The where clause here just says only show those FacilityID's and associated records if the FacilityID exists in your original query (CTE) (107) If we needed data from the CTE we'd join to it; but as it's simply restricting data placing it in the where clause and using an exists will likely be more efficient.
I'm incredibly new to SQL and working on completing some assignments in order to advance my knowledge. I found myself stuck on a problem, though.
I have to find the total profit on items by using multiplication and subtraction, which I have completed with the following commands:
select
production.product.ProductID,
StandardCost,
sales.SalesOrderDetail.OrderQty,
UnitPrice,
(sales.SalesOrderDetail.UnitPrice*sales.SalesOrderDetail.OrderQty)-
(production.product.StandardCost*sales.salesorderdetail.OrderQty) as
'Total Profit'
from
sales.SalesOrderDetail,
production.product
What I need to do is sum the total profit and group it by the ProductID in order to find the most profitable items and the least profitable. I thought this would work:
select
production.product.ProductID,
StandardCost,
sales.SalesOrderDetail.OrderQty,
UnitPrice,
sum((sales.SalesOrderDetail.UnitPrice*sales.SalesOrderDetail.OrderQty)-
(production.product.StandardCost*sales.salesorderdetail.OrderQty)) as
'Total Profit'
from
sales.SalesOrderDetail,
production.product
group by
Production.Product.ProductID
However, I receive the following error:
Column 'production.product.StandardCost' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I'm at a loss on where to continue. I tried rearranging and doing inner/left joins, but I've been unsuccessful.
so for grouping you need to aggregate or include in the group by statement.
you are grouping by the productID but the other columns are not aggregated and are not in the group by statement.
a correction could be (depending on how you want to aggregate the other columns)
select
production.product.ProductID
, avg(StandardCost) as AvgCost
, sum(sales.SalesOrderDetail.OrderQty) as TotalQuantity
, avg(UnitPrice) as AvgUnitPrice
, sum((sales.SalesOrderDetail.UnitPrice*sales.SalesOrderDetail.OrderQty)-
(production.product.StandardCost*sales.salesorderdetail.OrderQty)) as [Total Profit]
from sales.SalesOrderDetail
, production.product
group by Production.Product.ProductID
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.
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.
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