how to use count with where clause in join query - sql

SELECT
DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT
I have tried several combination but I keep getting error
Column 'DEPTMASTER.DeptID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
I also add group by but it's not working

WHen using count like that you need to group on the selected columns,
ie.
SELECT
DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT'
GROUP BY DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT

you miss group by
SELECT DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT
group by DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT

All aggregate functions like averaging, counting,sum needs to be used along with a group by function. If you dont use a group by clause, you are performing the function on all the rows of the table.
Eg.
Select count(*) from table;
This returns the count of all the rows in the table.
Select count(*) from table group by name
This will first group the table data based on name and then return the count of each of these groups.
So in your case, if you want the countof USRMST.UID, group it by all the other columns in the select list.

Related

Get Max from a joined table

I write this script in SQL server And I want get the food name with the Max of order count From this Joined Table . I can get Max value correct but when I add FoodName is select It give me an error.
SELECT S.FoodName, MAX(S.OrderCount) FROM
(SELECT FoodName,
SUM(Number) AS OrderCount
FROM tblFactor
INNER JOIN tblDetail
ON tblFactor.Factor_ID = tblDetail.Factor_ID
WHERE FactorDate = '2020-10-30'
GROUP BY FoodName)S
Here is The Error Message
Column 'S.FoodName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
also I know I can use order by and top to achieve the food Name and Max order number but I want use the way I use in this script . Thank you for your answers
If I follow you correctly, you can use ORDER BY and TOP (1) directly on the result of the join query:
SELECT TOP (1) f.FoodName, SUM(d.Number) AS OrderCount
FROM tblFactor f
INNER JOIN tblDetail d ON f.Factor_ID = d.Factor_ID
WHERE f.FactorDate = '2020-10-30'
GROUP BY f.FoodName
ORDER BY OrderCount DESC
Notes:
I added table aliases to the query, and prefixed each column with the table it (presumably !) comes from; you might need to review that, as I had to make assumptions
If you want to allow top ties, use TOP (1) WITH TIES instead
You have an aggregation function in the outer query MAX() and an unaggregated column. Hence, the database expects a GROUP BY.
Instead, use ORDER BY and LIMIT:
SELECT FoodName, SUM(Number) AS OrderCount
FROM tblFactor f INNER JOIN
tblDetail d
ON fd.Factor_ID = d.Factor_ID
WHERE FactorDate = '2020-10-30'
GROUP BY FoodName
ORDER BY OrderCount DESC
LIMIT 1;
Note: In a query that references multiple tables, you should qualify all column references. It is not clear where the columns come from, so I cannot do that for this query.

How to fix "Column 'ColumnName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

Needing to fix the mentioned code error for my SQL query
Error: "Column 'ColumnName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
I am under the impression that an aggregate function needs to be implemented, however I do not understand how.
My query:
SELECT
TransactionID,
InvoiceSum.TransNum,
PosTransaction.OrderID,
PosTransaction.PatientID,
Patient.ID,
Patient.MedicalRecordNum,
PosTransaction.OfficeNum AS Pos_OfficeNum,
Patient.ExamOffice,
TransactionDate,
Patient.FirstName,
Patient.LastName,
Patient.BirthDate,
Patient.Sex,
Item.ItemNum,
Item.ItemName
FROM PosTransaction Inner Join Patient ON PosTransaction.PatientID =
Patient.ID
Inner Join InvoiceSum ON PosTransaction.TransactionID =
InvoiceSum.TransNum
Inner Join InvoiceDet ON InvoiceSum.InvoiceID = InvoiceDet.InvoiceID
Inner Join Item ON InvoiceDet.ItemID = Item.ID
GROUP BY Patient.ID
ORDER BY TransactionDate
I am expecting to see duplicate customer names to be removed from the output once properly I understand how to use GROUP BY.
If you only group by patient.ID, what will happen to other columns?
(The server does not know what it should do, so it raises an error)
The server does not know what you want to do with the other columns.
(So You need the aggregate function(s) to tell the SQL server)
Simple example:
ID|salary
01|1000
01|2000
01|3000
If I only group by id here:
select id, salary
from sample
group by id
How do you want to calculate salary? Sum, max, min?
So you need the aggregate function:
select id, sum(salary)
from sample
group by id
Comment below if you have any questions.

Oracle SQL sum transactions by distinct customer id

I need to select the sum of transaction columns, count # of transactions, all by distinct customer ids. I have tried a few nested queries as well as something like the following:
select distinct(customer_id), sum(tran_amt), count(tran)
from tran_table
inner join tender_table;
The tender_table has the customer id so I have to join it.
You are using group functions, but you don't have a "group by" clause, I think this will give you the correct answer:
SELECT customer_id, SUM(tran_amt), COUNT(tran)
FROM tran_table INNER JOIN tender_table
GROUP BY CUSTOMER_ID;
I am guessing you want something like this:
select te.customer_id, sum(t.tran_amt), count(*)
from tran_table t inner join
tender_table te
on t.?? = te.??
group by te.customer_id;
You need join conditions and a group by clause. The ?? is for the columns used for the join, which your question does not specify.
Try this :
select tb_tran.customer_id, sum(tran_amt), count(tran)
from tran_table tb_tran inner join tender_table tb_tender
on tb_tran.customer_id = tb_tender.customer_id
group by tb_tran.customer_id;

Column 'ITEMS_MASTER.QUANTITY' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

Select
ID.ITEM_MODEL,
SUM(ID.AMOUNT) as Total_Amount,
AVG(ID.RATE) as Avg_Rate,
IM.QUANTITY
From
ITEM_DETAILS ID
inner join
ITEMS_MASTER IM on ID.ITEM_MODEL = IM.ITEM_MODEL
where IM.ITEM_MODEL='keyboard'
Group by
ID.ITEM_MODEL
I wrote above query, I want to extract data from two tables ITEM_DETAILS and ITEMS_MASTERS but when I run this it is showing me this error:
Column 'ITEMS_MASTER.QUANTITY' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Can anyone suggest me the correct way of doing this.
Try this:
SELECT IM.ITEM_MODEL, IM.QUANTITY,
SUM(ID.AMOUNT) as Total_Amount,
AVG(ID.RATE) as Avg_Rate
FROM ITEMS_MASTER IM
INNER JOIN ITEM_DETAILS ID ON ID.ITEM_MODEL = IM.ITEM_MODEL
WHERE IM.ITEM_MODEL = 'keyboard'
GROUP BY IM.ITEM_MODEL, IM.QUANTITY
Generally speaking, when you have a parent table (ITEMS_MASTER) that has multiple rows from a child table (ITEM_DETAILS), you want to GROUP BY the columns in your parent table. This is slightly more logical and on some databases this performs better.
You could try adding IM.QUANTITY to the group by clause,
Group by
ID.ITEM_MODEL,
IM.QUANTITY

Sum SQL statement outputs many rows when I expect only one

So I have 3 tables joined as shown:
What I want to do is query for the sum of all the holdings that fall into the criteria specified for the clients in my query. Here is what I have:
SELECT Sum(Holdings.HoldingValue) AS SumOfHoldingValue
FROM (Clients INNER JOIN Accounts
ON Clients.ClientID = Accounts.ClientID)
INNER JOIN Holdings
ON Accounts.AccountID = Holdings.AccNum
GROUP BY Holdings.HoldingDate, Clients.Active, Clients.RiskCode, Clients.NewClient, Clients.BaseCurrency, Clients.ClientID
HAVING (((Holdings.HoldingDate)=#3/31/2013#)
AND ((Clients.Active)=True)
AND ((Clients.RiskCode) In (1,2))
AND ((Clients.NewClient)=True)
AND ((Clients.BaseCurrency)='GBP')
AND ((Clients.ClientID) Not In (10022,10082,10083)));
Here's an example of what I get as the result:
SumOfHoldingValue
1056071.96
466595.6
1074459.38
371142.54
814874.42
458203.65
8308697.09
254733.94
583796.33
443897.76
203787.11
1057445.84
1058751.26
317507.43
So there are quite a few criteria for the client table but the result is a list of SumOfHoldingValue when what I want is just one number. I.e. the sum of all the holding values. Why is it not grouping them all together to form one total?
Since you're not computing any aggregates on the values in the HAVING clause, I think you just want this:
SELECT Sum(Holdings.HoldingValue) AS SumOfHoldingValue
FROM (Clients INNER JOIN Accounts
ON Clients.ClientID = Accounts.ClientID)
INNER JOIN Holdings
ON Accounts.AccountID = Holdings.AccNum
WHERE (((Holdings.HoldingDate)=#3/31/2013#)
AND ((Clients.Active)=True)
AND ((Clients.RiskCode) In (1,2))
AND ((Clients.NewClient)=True)
AND ((Clients.BaseCurrency)='GBP')
AND ((Clients.ClientID) Not In (10022,10082,10083)));
Which, with no GROUP clause will produce a single GROUP (over the entire set) and produce a single row.
If you just want totals - remove the group by. With the group by clause it gives you totals for every group separately.
If you need to filter data put the condition into Where clause instead
Your query contains a group by clause which returns each group on its own line.
You are also using a having clause. The having clause is applied after the group by. Usually, it would contain aggregation functions -- such as having count(*) > 1. In your case, it is used as a where clause.
Try rewriting the query like this:
SELECT Sum(Holdings.HoldingValue) AS SumOfHoldingValue
FROM (Clients INNER JOIN Accounts
ON Clients.ClientID = Accounts.ClientID)
INNER JOIN Holdings
ON Accounts.AccountID = Holdings.AccNum
WHERE (((Holdings.HoldingDate)=#3/31/2013#)
AND ((Clients.Active)=True)
AND ((Clients.RiskCode) In (1,2))
AND ((Clients.NewClient)=True)
AND ((Clients.BaseCurrency)='GBP')
AND ((Clients.ClientID) Not In (10022,10082,10083)));