SUM value when another column value is DISTINCT - sql

I was wondering how I can SUM the values of a column based on another column's values being distinct like below. I tried the following two ways, each giving errors due to the aggregate function. I am trying to get NonDistinctTotals with the queries below.
SELECT SUM(InvoiceSaleAmt) AS NonDistinctTotals, SUM(case when count(*) over (partition by InvoiceNo) = 1 then InvoiceSaleAmt else 0 END) as DistinctTotals, SUM(CASE WHEN PaymentType= 'CASH' THEN CashTotal ELSE 0 END) AS CashTotal
FROM #InvoiceTable a
group by LocationId, InvoiceNo
Error: Windowed functions cannot be used in the context of another windowed function or aggregate.
SELECT SUM(InvoiceSaleAmt) AS NonDistinctTotals, SUM(CASE WHEN InvoiceNoin (SELECT DISTINCT InvoiceNofrom #InvoiceTable) THEN InvoiceSaleAmt else 0 END) as DistinctTotals, SUM(CASE WHEN PaymentType= 'CASH' THEN CashTotal ELSE 0 END) AS CashTotal
FROM #InvoiceTable a
group by LocationId, InvoiceNo
Error: Cannot perform an aggregate function on an expression containing an aggregate or a subquery.

Use a subquery:
SELECT SUM(InvoiceSaleAmt) AS NonDistinctTotals,
SUM(case when cnt = 1 then InvoiceSaleAmt else 0 END) as DistinctTotals,
SUM(CASE WHEN PaymentType = 'CASH' THEN CashTotal ELSE 0 END) AS CashTotal
FROM (SELECT it.*, COUNT(*) over (partition by InvoiceNo) as cnt
FROM #InvoiceTable it
) it
GROUP BY LocationId, InvoiceNo

Related

tsql - pivot sum of employee

I have here a sample table data which i want to use pivot and make my DedCode data into column.
the AMount example is already computed to its total but how can i count the number of employee if it is same with branch,deptcode and emptype.
my sample table data.
expected output:
You can use conditional aggregation:
select branch, deptcode, emptype, sum(empcount) as empcount,
sum(case when dedcode = 'PHIC' then amount else 0 end) as phic,
sum(case when dedcode = 'SLOAN' then amount else 0 end) as sloan,
sum(case when dedcode = 'VLOAN' then amount else 0 end) as vloan
from t
group by branch, deptcode, emptype;

How to correct error when aggregating from subquery

I have a query that looks like this:
SELECT store_id,
(CASE WHEN txns_A>0 AND txns_B=0 THEN 'A Only' WHEN txns_A=0 AND txns_B>0 THEN 'B Only' END) A_B_indicator,
sum(1) cnt_customers,
sum(spend_A+spend_B)/sum(txns_A+txns_B) avg_receipt
FROM(
SELECT store_id, cust_id
SUM(CASE WHEN A_B_indicator='A' THEN spend else 0 end) spend_A,
SUM(CASE WHEN A_B_indicator='B' THEN spend else 0 end) spend_B,
SUM(CASE WHEN A_B_indicator='A' THEN spend else 0 end) txns_A,
SUM(CASE WHEN A_B_indicator='B' THEN spend else 0 end) txns_B
FROM table1
GROUP BY store_id, cust_id
) table2;
However, this generates an error because store_id is not in a GROUP BY clause. When I rewrite the query to include a GROUP BY store_id clause, it complains that the aggregate columns are not in the Group By. However, if I add them by rewriting the Group By to be Group BY 1,2,3,4, this also generates an error (Not yet supported place for UDAF Sum).
How can I rewrite this query to be error-free?
You can write this as:
SELECT store_id,
(CASE WHEN SUM(txns_A) > 0 AND SUM(txns_B) = 0 THEN 'A Only'
WHEN SUM(txns_A) = 0 AND SUM(txns_B) > 0 THEN 'B Only'
END) as A_B_indicator,
COUNT(*) as cnt_customers,
SUM(spend_A+spend_B)/sum(txns_A+txns_B) as avg_receipt
FROM (SELECT store_id, cust_id
SUM(CASE WHEN A_B_indicator='A' THEN spend else 0 end) as spend_A,
SUM(CASE WHEN A_B_indicator='B' THEN spend else 0 end) as spend_B,
SUM(CASE WHEN A_B_indicator='A' THEN spend else 0 end) as txns_A,
SUM(CASE WHEN A_B_indicator='B' THEN spend else 0 end) as txns_B
FROM table1
GROUP BY store_id, cust_id
) table2
GROUP BY store_id;

SQL CASE WHEN THEN logics of calculating the types of a column

Have a tableA like this:
I wanna receive a tableŠ˜ like this (group by startTime and endTime, count of Severity in cnt column and count of every type of Severity in a distinct column):
The simple count (cnt column) works fine. But with the other I tired CASE WHEN THEN logics and it seems not working (line 10 for example). Can you please assist me with SQL query in this case.
You need conditional aggregation :
select starttime, endtime, count(*),
sum(case when severity = 'low' then 1 else 0 end),
sum(case when severity = 'med' then 1 else 0 end),
sum(case when severity = 'high' then 1 else 0 end)
from table t
group by starttime, endtime;
Try below query: with case when
select starttime, endtime, count(severity) as cnt, count(case when severity='LOW' then 1 end) cnt_low,count(case when severity='MED' then 1 end) cnt_med,count(case when severity='HIGH' then 1 end) as cnt_high
from tablename
group by starttime, endtime
use case when and aggregate function sum
select startTime , endTime,count(*) as Cnt,
sum( case when Severity='MED' then 1 else 0 end) as cntMed,
sum( case when Severity='LOW' then 1 else 0 end) as cntLow,
sum( case when Severity='HIGH' then 1 else 0 end) as cntHIGH from yourtable
group by startTime , endTime

Group by in sql for two conditions

I have this table
SELECT
[WeldStatus]
,PackageId
FROM [SPMS2].[dbo].[JointHistory]
How can I group by this query to calculate total testpackage and total accept and total remain?
For example for packageid=6030 I need this:
packageid total accept remain
6030 4 3 1
Use CASE and Group By
SELECT
PackageId,
count(*) as total,
sum(case [WeldStatus] when 'Accept' then 1 end) as accept,
sum(case [WeldStatus] when 'accept' then 0 else 1 end) as remain
FROM [SPMS2].[dbo].[JointHistory]
group by PackageId;
SELECT
packageid
,count(*) as 'total'
,sum(case when weldstatus = 'Accept' then 1 else 0 end) as 'accept'
,sum(case when weldstatus is null then 1 else 0 end) as 'remain'
FROM [SPMS2].[dbo].[JointHistory]
group by packageid
"sum(case when..." has saved me so many times. NULLs can be a pain but the case when saves you.
You can use CASE expression with in your aggregation to achieve your desired output.
SELECT
PackageId,
SUM (CASE WHEN WeldStatus = 'Accept' THEN 1 ELSE 0 END) AS AcceptCount,
SUM (CASE WHEN WeldStatus IS NULL THEN 1 ELSE 0 END) AS RemainCount,
COUNT (*) AS Total
FROM [SPMS2].[dbo].[JointHistory]
GROUP BY PackageId
select packageid, SUM(TOTAL), SUM(ACCEPT), SUM(REMAIN) from (
select packageid, 1 as TOTAL,
case
when WeldStatus='Accept' then 1 else 0
END as ACCEPT,
case
when WeldStatus IS NULL then 1 else 0
END as REMAIN
from JointHistory
) group by packageid
If WeldStatus only takes on the values of 'Accept' or NULL, then a simple method is:
SELECT PackageId, count(*) as total,
count(WeldStatus) as accept,
count(*) - count(WeldStatus) as remain
FROM [SPMS2].[dbo].[JointHistory] jh
GROUP BY PackageId;
I'm the first to admit that this relies on the assumption of having a single value or NULL.
SELECT PackageId,
COUNT(*) AS total,
SUM(CASE WHEN [WeldStatus] = 'Accept' THEN 1 END) AS accept,
SUM(CASE WHEN ISNULL([WeldStatus],'') = '' THEN 1 ELSE 0 END) AS remain
FROM [SPMS2].[dbo].[JointHistory]
group by PackageId;

How to have one row multiple columns instead of multiple rows

I have the following data:
In SQL Server How can I have group by weekdate so I have only one row for each weekdate, example for the weekdate 2015-11-14:
Any clue?
Use conditional aggregation.
select cast(weekdate as date),
sum(case when permittype = 0 then total else 0 end) as permittype0,
sum(case when permittype = 1 then total else 0 end) as permittype1
from tablename
group by cast(weekdate as date)
I would do this using conditional aggregation:
select weekdate,
sum(case when permittype = 0 then total else 0 end) as permitttype0,
sum(case when permittype = 1 then total else 0 end) as permitttype1
from followingdata t
group by weekdate
order by weekdate;
You can also use pivot syntax, if you prefer.