how to have a where clause in an aggregate function SQL Server - sql

OK, I have a table that looks like this:
ID AMOUNT PAID
1 50.00 Y
2 100.00 N
3 200.00 Y
And I want to see something like:
Total Due Paid
350.00 1 2
So my SQL would look like (in my head...it doesnt work that way, which is why I'm here )
select sum(amount)
,count(paid where paid='y') as due
,count(paid where paid='n') as paid
from sometable where something=somethingelse

select sum(amount) as total,
sum(case paid when 'N' then 1 else 0 end) as due,
sum(case paid when 'Y' then 1 else 0 end) as paid
from sometable where something=somethingelse

One more option
SELECT SUM(AMOUNT) AS Total,
COUNT(CASE WHEN PAID = 'Y' THEN PAID END) AS Paid,
COUNT(CASE WHEN PAID = 'N' THEN PAID END) AS Due
FROM sometable
WHERE something = somethingelse
Demo om SQLFiddle

Related

Get users that have at least one product code and also more than 10 of the other product code

The table that needs to be queried looks like this:
ID
UserID
ProductCodes
1
33
9999
2
456
3051
3
456
9999
4
456
3051
4
33
9999
How would I write a SQL query to find out which users have at least one productCodes = '9999' and also have more than 10 productCodes <> '9999'?
You can use GROUP BY and HAVING:
SELECT
UserID
FROM dbo.YourTable
GROUP BY
UserId
HAVING SUM(CASE WHEN ProductCodes = '9999' THEN 1 ELSE 0 END) >= 1
AND COUNT(DISTINCT ProductCodes) >= 11
;
Use Case or Intersect (case is more performant)
SELECT UserID, SUM (case when ProductCodes='9999' then 1 else 0 end) PC9999
, SUM (case when ProductCodes<>'9999' then 1 else 0 end) PCNot9999
FROM dbo.Users
WHERE ProductCodes='9999'
GROUP BY UserID
HAVING SUM (case when ProductCodes='9999' then 1 else 0 end)>0
AND SUM (case when ProductCodes<>'9999' then 1 else 0 end) >10
I ended up going with this. It allows us to get specific with how many times a '9999' product code has been used in comparison with other codes.
SELECT
UserID
FROM Session_Hst
GROUP BY
UserID
HAVING SUM(CASE WHEN ProductCodes = '9999' THEN 1 ELSE 0 END) >= 1
AND COUNT(CASE WHEN ProductCodes <> '9999' THEN 1 ELSE null END ) >= 10
;

Filter results within groups sql

In the table below, I want to know how many customers ordered lunch without a coffee. The result would be 1, for sale ID 300, because two lunches were ordered but only one coffee.
It’s been 8 years since I last used SQL! How do I say “group the records by sale ID and for each group, drop groups where there is no lunch or COUNT(coffee) < COUNT(lunch)"?
SALE ID
Product
100
coffee
100
lunch
200
coffee
300
lunch
300
lunch
300
coffee
here is one way:
select count(*) from (
select saleID
from tablename
group by saleID
having sum(case when product ='coffee' then 1 else 0 end) = 0
and sum(case when product ='lunch' then 1 else 0 end) = 1
) t
You can do it with aggregation and the conditions in the HAVING clause.
This query:
SELECT sale_id
FROM tablename
GROUP BY sale_id
HAVING SUM(product = 'lunch') > SUM(product = 'coffee');
returns all the sale_ids that you want.
This query:
SELECT DISTINCT COUNT(*) OVER () counter
FROM tablename
GROUP BY sale_id
HAVING SUM(product = 'lunch') > SUM(product = 'coffee');
returns the number of sale_ids that you want.
See the demo.
select count(*) from (
--in this subquery calculate counts and ignore items that haven't any lunch
select
saleID, sum(case when product ='coffee' then 1 else 0 end) as coffee,
sum(case when product ='lunch' then 1 else 0 end) lunch
from tablename
group by saleID
having sum(case when product ='lunch' then 1 else 0 end) >= 1 --Here we are ignoring all items haven't any lunch
) t
where lunch > coffee -- we check second condition be ok

Count same column twice based on condition

i have the following query to count the Amount field as Countused if Account_Fkey is not null
select Amount as amount2, Count(Amount) as CountUsed from tblGiftCards
where Account_Fkey is not null
group by Amount
result:
amount2 CountUsed
25 3
50 10
100 5
i want to calculate the amount of Amount as Amount not used in the same query where account fkey is null. So, the result will be:
amount2 CountUsed CountUnused
25 3 1
50 10 0
100 5 2
Thanks
You could use a conditional aggregation
select Amount as amount2
, sum( case when Account_Fkey is not null
and Amount is not null then 1 else 0 end) CountUsed
, sum( case when Account_Fkey is null
and Amount is not null then 1 else 0 end) CountNotUsed
from tblGiftCards
group by Amount
Try
select tab.amount2 , CountUsed , CountUnUsed from
(select Amount as amount2, Count(Amount) as CountUsed from tblGiftCards
where Account_Fkey is not null
group by Amount
) tab,
(select Amount as amount2, Count(Amount) as CountUnUsed from tblGiftCards
where Account_Fkey is null
group by Amount
)tab2
where tab.amount2 = tab2.amount2
I would simplify the logic and express this as:
select Amount as amount2, count(Account_Fkey) as CountUsed,
(count(*) - count(Account_Fkey)) as CountNotUsed
from tblGiftCards
where Amount is not null
group by Amount

trying to find customers and their total sales who have shopped for brand1 as well as brand2

I am trying to find the customer who have bought brand1 and brand 2 and also the total sum of the dollar value spent. I have made a sample data base which has all the details.
I am able to get the customers who have bought both the brands, but the dollar amount should equal to the the sum of dollar amount spend in brand 1 and brand 2.
this is the link to the sample database:
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=8a478b5743099ea5c76acd08e22c0c53
If I understand correctly, you can just use aggregation with an appropriate having clause:
select individual_id, sum(dollar_value_us)
from transaction_detail_mv
group by individual_id
having sum( case when brand_org_code = 'BRAND1' then 1 else 0 end) > 0 and
sum( case when brand_org_code = 'BRAND2' then 1 else 0 end) > 0
use corelated subquery
select individual_id, SUM (dollar_value_US) from
transaction_detail_mv t1
where t1.brand_org_code IN ('BRAND1','BRAND2')
AND EXISTS (SELECT 1
FROM TRANSACTION_DETAIL_MV t2 WHERE t1.individual_id=t2.individual_id
and BRAND_ORG_CODE = 'BRAND2')
GROUP BY
individual_id
INDIVIDUAL_ID SUM(DOLLAR_VALUE_US)
1 40
2 22
5 22

Using distinct and case for two separate columns

I am counting cases by year using the following code:
COUNT(CASE WHEN Year(FilingDate)=2008 THEN 1 ELSE NULL END) AS '2008'
and I want to only count these cases when another column is distinct. The other column is called 'FilingDate' What I imagine would look something like this:
COUNT(CASE distinct (DocketNumber) WHEN Year(FilingDate)=2008 THEN 1 ELSE NULL END) AS '2008',
The Sample Records:
DocketNumber FilingDate
123 2008
123 2008
123 2008
111 2009
112 2009
I would just like to recieve = 1
Any Ideas?
Thanks
Use option with SUBQUERY and GROUP BY clause
SELECT COUNT(CASE WHEN YearFilingDate = 2008 THEN 1 END) AS '2008'
FROM
(
SELECT Year(FilingDate) AS YearFilingDate, DocketNumber
FROM dbo.test55
GROUP BY Year(FilingDate), DocketNumber
) x
Demo on SQLFiddle
SELECT COUNT(CASE WHEN Year(FilingDate)=2008 THEN 1 ELSE NULL END) AS '2008'
GROUP BY DocketNumber
may be.