Getting Columns Related to GROUP BY Column - sql-server

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

Related

sub-query return more than 1 value this is not permitted when the subquery follows = , >=,>,<,<= [duplicate]

I run the following query:
SELECT
orderdetails.sku,
orderdetails.mf_item_number,
orderdetails.qty,
orderdetails.price,
supplier.supplierid,
supplier.suppliername,
supplier.dropshipfees,
cost = (SELECT supplier_item.price
FROM supplier_item,
orderdetails,
supplier
WHERE supplier_item.sku = orderdetails.sku
AND supplier_item.supplierid = supplier.supplierid)
FROM orderdetails,
supplier,
group_master
WHERE invoiceid = '339740'
AND orderdetails.mfr_id = supplier.supplierid
AND group_master.sku = orderdetails.sku
I get the following error:
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Any ideas?
Try this:
SELECT
od.Sku,
od.mf_item_number,
od.Qty,
od.Price,
s.SupplierId,
s.SupplierName,
s.DropShipFees,
si.Price as cost
FROM
OrderDetails od
INNER JOIN Supplier s on s.SupplierId = od.Mfr_ID
INNER JOIN Group_Master gm on gm.Sku = od.Sku
INNER JOIN Supplier_Item si on si.SKU = od.Sku and si.SupplierId = s.SupplierID
WHERE
od.invoiceid = '339740'
This will return multiple rows that are identical except for the cost column. Look at the different cost values that are returned and figure out what is causing the different values. Then ask somebody which cost value they want, and add the criteria to the query that will select that cost.
Check to see if there are any triggers on the table you are trying to execute queries against. They can sometimes throw this error as they are trying to run the update/select/insert trigger that is on the table.
You can modify your query to disable then enable the trigger if the trigger DOES NOT need to be executed for whatever query you are trying to run.
ALTER TABLE your_table DISABLE TRIGGER [the_trigger_name]
UPDATE your_table
SET Gender = 'Female'
WHERE (Gender = 'Male')
ALTER TABLE your_table ENABLE TRIGGER [the_trigger_name]
SELECT COLUMN
FROM TABLE
WHERE columns_name
IN ( SELECT COLUMN FROM TABLE WHERE columns_name = 'value');
note: when we are using sub-query we must focus on these points:
if our sub query returns 1 value in this case we need to use (=,!=,<>,<,>....)
else (more than one value), in this case we need to use (in, any, all, some )
cost = Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier
where Supplier_Item.SKU=OrderDetails.Sku and
Supplier_Item.SupplierId=Supplier.SupplierID
This subquery returns multiple values, SQL is complaining because it can't assign multiple values to cost in a single record.
Some ideas:
Fix the data such that the existing subquery returns only 1 record
Fix the subquery such that it only returns one record
Add a top 1 and order by to the subquery (nasty solution that DBAs hate - but it "works")
Use a user defined function to concatenate the results of the subquery into a single string
The fix is to stop using correlated subqueries and use joins instead. Correlated subqueries are essentially cursors as they cause the query to run row-by-row and should be avoided.
You may need a derived table in the join in order to get the value you want in the field if you want only one record to match, if you need both values then the ordinary join will do that but you will get multiple records for the same id in the results set. If you only want one, you need to decide which one and do that in the code, you could use a top 1 with an order by, you could use max(), you could use min(), etc, depending on what your real requirement for the data is.
I had the same problem , I used in instead of = , from the Northwind database example :
Query is : Find the Companies that placed orders in 1997
Try this :
SELECT CompanyName
FROM Customers
WHERE CustomerID IN (
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Instead of that :
SELECT CompanyName
FROM Customers
WHERE CustomerID =
(
SELECT CustomerID
FROM Orders
WHERE YEAR(OrderDate) = '1997'
);
Either your data is bad, or it's not structured the way you think it is. Possibly both.
To prove/disprove this hypothesis, run this query:
SELECT * from
(
SELECT count(*) as c, Supplier_Item.SKU
FROM Supplier_Item
INNER JOIN orderdetails
ON Supplier_Item.sku = orderdetails.sku
INNER JOIN Supplier
ON Supplier_item.supplierID = Supplier.SupplierID
GROUP BY Supplier_Item.SKU
) x
WHERE c > 1
ORDER BY c DESC
If this returns just a few rows, then your data is bad. If it returns lots of rows, then your data is not structured the way you think it is. (If it returns zero rows, I'm wrong.)
I'm guessing that you have orders containing the same SKU multiple times (two separate line items, both ordering the same SKU).
The select statement in the cost part of your select is returning more than one value. You need to add more where clauses, or use an aggregation.
The error implies that this subquery is returning more than 1 row:
(Select Supplier_Item.Price from Supplier_Item,orderdetails,Supplier where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
You probably don't want to include the orderdetails and supplier tables in the subquery, because you want to reference the values selected from those tables in the outer query. So I think you want the subquery to be simply:
(Select Supplier_Item.Price from Supplier_Item where Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID )
I suggest you read up on correlated vs. non-correlated subqueries.
As others have suggested, the best way to do this is to use a join instead of variable assignment. Re-writing your query to use a join (and using the explicit join syntax instead of the implicit join, which was also suggested--and is the best practice), you would get something like this:
select
OrderDetails.Sku,
OrderDetails.mf_item_number,
OrderDetails.Qty,
OrderDetails.Price,
Supplier.SupplierId,
Supplier.SupplierName,
Supplier.DropShipFees,
Supplier_Item.Price as cost
from
OrderDetails
join Supplier on OrderDetails.Mfr_ID = Supplier.SupplierId
join Group_Master on Group_Master.Sku = OrderDetails.Sku
join Supplier_Item on
Supplier_Item.SKU=OrderDetails.Sku and Supplier_Item.SupplierId=Supplier.SupplierID
where
invoiceid='339740'
Even after 9 years of the original post, this helped me.
If you are receiving these types of errors without any clue, there should be a trigger, function related to the table, and obviously it should end up with an SP, or function with selecting/filtering data NOT USING Primary Unique column. If you are searching/filtering using the Primary Unique column there won't be any multiple results. Especially when you are assigning value for a declared variable. The SP never gives you en error but only an runtime error.
"System.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated."
In my case obviously there was no clue, but only this error message. There was a trigger connected to the table and the table updating by the trigger also had another trigger likewise it ended up with two triggers and in the end with an SP. The SP was having a select clause which was resulting in multiple rows.
SET #Variable1 =(
SELECT column_gonna_asign
FROM dbo.your_db
WHERE Non_primary_non_unique_key= #Variable2
If this returns multiple rows, you are in trouble.

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

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.

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.

postgreSQL select additional columns that aren't used in aggregate function

I'm trying to write a query in PostgreSQL and I'm getting a little frustrated because it works in other database engines. I need to select the top 5 users from a given joins table like this:
SELECT users.*,
COUNT(deals.id) AS num_deals
FROM users, deals
WHERE deals.users_id = users.id
GROUP BY users.id
ORDER BY num_deals LIMIT 5;
I need the top 5 users. This code works in sqlite, mysql, etc, yet PostgreSQL refuses to select additional fields that aren't used in aggregate functions. I'm getting the following error:
PGError: ERROR: column "users.id" must appear in the GROUP BY clause or be used in an aggregate function
How can I do this in PostgreSQL??
You could try:
SELECT users.*, a.num_deals FROM users, (
SELECT deal.id as dealid, COUNT(deals.id) AS num_deals
FROM deals
GROUP BY deal.id
) a where users.id = a.dealid
ORDER BY a.num_deals DESC
LIMIT 5
Assuming that users.id IS a PK, then you can either
wait for 9.1
group by all fields
use an aggregate (i.e. max() ) on all fields
One other solution that works is to use all attributes implicitly in GROUP BY
Thus following will be final query
SELECT users.*,
COUNT(deals.id) AS num_deals
FROM users, deals
WHERE deals.users_id = users.id
GROUP BY users.id, users.name, users.attrib1, ..., users.attribN
ORDER BY num_deals LIMIT 5;
If you are using framework like rails then you can implement this easily with Model.column_names function.
Just in case of somebody wants ANSI-92 standard solution and doesn't like 'Oracle' way to join tables...
SELECT users.*, num_deals
FROM users
JOIN
(SELECT deals.users_id as users_id, count(deals.users_id) as num_deals
FROM deals
GROUP BY deals.id) grouped_user_deals
ON grouped_user_deals.users_id = users.id
ORDER BY num_deals DESC
LIMIT 5;

Resources