How can I do grouping in my case using SQL Server? - sql

I wants to calculate sum of quantity based on Quantity value
For Example
ItemNo Quantity
------------------
111 5
111 -2
111 3
112 10
I want to do grouping by ItemNo and calculate like below
ItemNo Quantity Positive Negative
-----------------------------------------
111 6 8 -2
112 10 10 0
I tried like this
SELECT
ItemNo,
Sum(Quantity),
Case when Quantity >= 0 then sum(quantity) else 0 end POSITIVE,
Case when Quantity < 0 then sum(quantity) else 0 end Negative
From
Sales
Group By
ItemNo,
Quantity
I know this grouping is wrong. How my query should be?
thanks

Just put the SUM() around your CASE() statement:
SELECT
ItemNo,
Sum(Quantity),
SUM(Case when Quantity >= 0 then quantity else 0 end) POSITIVE,
SUM(Case when Quantity < 0 then quantity else 0 end) Negative
From
Sales
Group By
ItemNo;
Also, remove Quantity from your GROUP BY. You are aggregating quantity with a sum() so it's nonsense to GROUP BY it as well.

I would leave this as a comment to JNevill's answer if I had the reputation, but you would also want to give the quantity sum an alias to get the results in the question. For example: SELECT
ItemNo,
Sum(Quantity) Quantity,
SUM(Case when Quantity >= 0 then Quantity else 0 end) Positive,
SUM(Case when Quantity < 0 then Quantity else 0 end) Negative
From
Sales
Group By
ItemNo;

Related

How to query for Total of Integer Records in SQL

I have a table structured like this;
shopid times
shop1 5
shop2 20
shop1 6
shop1 100
shop2 100
My work in progress query;
SELECT
sum(case when shopid='shop1' then times end) as shop1
,sum(case when shopid='shop2' then times end) as shop2
,sum(times) as total
from table3
group by shopid
order by shopid
Outcome
shop1 shop2 total
111 NULL 111
NULL 120 120
I need the TOTAL for each records, expected like this. Would you be able to point me to the right direction?
shop1 shop2 total
111 NULL 111
NULL 120 120
TOTAL 111 120 231
Why not just use a single query with a single row?
select sum(case when shopid = 'shop1' then times end) as shop1,
sum(case when shopid = 'shop2' then times end) as shop2,
sum(times) as total
from table3 ;
(You may want `where shopid in ('shop1', 'shop2').)
If you want different rows, then you don't need so many columns. You can get the total using GROUPING SETS:
select coalesce(shopid, 'Total'), sum(times)
from table3
group by grouping sets ( (shopid), () );
EDIT:
Or if you really want you can do:
select (case when shopid is null then 'Total' end),
sum(case when shopid = 'shop1' then times end) as shop1,
sum(case when shopid = 'shop2' then times end) as shop2,
sum(times) as total
from table3
group by grouping sets ( (shopid), () );

SQL query to compare the amount

I have a Claim table that holds the claim amount. I need to write a query to compare if the amount is the same or not.
SELECT
CLAIM_NO, SUM(TRAN_AMOUNT) AS Amount
FROM
CLMTABLE
WHERE
TRTYPE = 0
GROUP BY
CLAIM_NO
UNION ALL
SELECT
CLAIM_NO, SUM(TRAN_AMOUNT) AS Amount
FROM
CLMTABLE
WHERE
TRTYPE <> 0
GROUP BY
CLAIM_NO
OUTPUT
CLAIM_NO AMOUNT
-----------------
1234567890 883.00
1234567890 883.00
1234567891 990.00
1234567891 990.00
1234567892 883.00
1234567892 893.00
The last record the amount is not the same, i want to be able to spot the claim that the amount doesn't match.
Thanks, any help will be appreciated
Please use below query to find all such transaction:
SELECT CLAIM_NO,SUM(CASE WHEN TRTYPE=0 THEN ISNULL(TRAN_AMOUNT,0) ELSE 0 END) As Amount,
SUM(CASE WHEN TRTYPE<>0 THEN ISNULL(TRAN_AMOUNT,0) ELSE 0 END) AS Amount2
FROM CLMTABLE
GROUP BY CLAIM_NO
HAVING SUM(CASE WHEN TRTYPE=0 THEN ISNULL(TRAN_AMOUNT,0) ELSE 0 END) <> SUM(CASE WHEN TRTYPE<>0 THEN ISNULL(TRAN_AMOUNT,0) ELSE 0 END)
Use a CASE inside a SUM func to retrieve the difference between amount of different types.
SELECT claim_no, SUM(CASE WHEN trtype = 0 THEN tran_amount
ELSE -1*tran_amount
END) as delta
FROM clmtable
GROUP BY claim_no

Select multiple COUNTs for every day

I got a table of Visitors.
Visitor has the following columns:
Id
StartTime (Date)
Purchased (bool)
Shipped (bool)
For each day within the last 7 days, I want to select 3 counts of the Visitors who have that day as StartTime:
The count of total visitors
The count of total visitors where Purchased = true
The count of total visitors where Shipped = true
Ideally the returned result would be:
Day Total TotalPurchased TotalShipped
1 100 67 42
2 82 61 27
etc...
I am used to .NET Linq so this has proved to be quite a challenge for me.
All I have come up with so far is the following:
SELECT COUNT(*) AS Total
FROM [dbo].[Visitors]
WHERE DAY([StartTime]) = DAY(GETDATE())
It selects the total of the current day just fine, however I feel pretty stuck right now so it'd be nice if someone could point me in the right direction.
For the last 7 days use the query proposed by Stanislav but with this WHERE clause
SELECT DAY([StartTime]) theDay,
COUNT(*) AS Tot,
SUM(CASE WHEN Purchased=true THEN 1 ELSE 0 END) as TotPurch,
SUM(CASE WHEN Shipped=true THEN 1 ELSE 0 END) as TotShip
FROM [dbo].[Visitors]
WHERE [StartTime] BETWEEN GETDATE()-7 AND GETDATE()
GROUP BY DAY([StartTime])
SELECT COUNT(*) AS Total,
SUM(CASE WHEN Purchased=true THEN 1 ELSE 0 END) as TotalPurchased,
SUM(CASE WHEN Shipped=true THEN 1 ELSE 0 END) as TotalShipped
FROM [dbo].[Visitors]
WHERE DAY([StartTime]) = DAY(GETDATE())
and add GROUP BY DAY([StartTime]) as jarlh mentioned
Here's a simple select that will give you the dataset you want
SELECT DATEDIFF(day,StartTime, getdate())+1 as [Day], -- Add 1 to display 1 to 7 instead of 0 to 6
COUNT(*) as Total,
SUM(CASE WHEN Purchased = 1 THEN 1 ELSE 0 END) as TotalPurchased,
SUM(CASE WHEN Shipped = 1 THEN 1 ELSE 0 END) AS TotalShipped
FROM Visitors
WHERE DATEDIFF(day,startTime,GETDATE()) < 6
GROUP BY DATEDIFF(day,startTime,GETDATE())
ORDER BY 1
This query will not take into consideration the time component of the date.

How to subtract result of 2 queries grouped by a field

I have a table in this form:
id year type amount
1 2015 in 10
2 2015 out 5
3 2016 in 20
4 2016 out 1
...
The followin query will give me the sum of the amount of type = 'in' grouped by year:
SELECT year, sum(amount)
FROM table
WHERE type = in
GROUP BY year
How am I going to get the following result?
year sum(in) sum(out) "in-out"
2015 10 5 5
2016 20 1 19
sum(in) is the sum of the 'amount' where type='in'.
Use a CASE statement to handle the values of type.
SELECT year,
SUM(CASE WHEN type = 'in' THEN amount ELSE 0 END) AS sum_in,
SUM(CASE WHEN type = 'out' THEN amount ELSE 0 END) AS sum_out,
SUM(CASE WHEN type = 'in' THEN amount ELSE -amount END) AS in_out
FROM table
GROUP BY year;

count row with total

From tbl Department, I am trying to write a stored procedure to display output as shown below where I can find the count from each row based on following conditions:
Total = 100
Total >100 and <=200
Total >200 and <=300
Total >300
set #select = 'select count(*) as Orders, sum (tbl.Expenses) as Total from tbl group by tbl.Department'
So, how can I dynamically get the output for 4 conditions as shown above based on my #select statement.
I think you just want conditional aggregation:
select sum(case when total = 100 then 1 else 0 end) as condition1,
sum(case when total > 100 and total <= 200 then 1 else 0 end) as condition2,
sum(case when total > 200 and total <= 300 then 1 else 0 end) as condition3,
sum(case when total > 300 then 1 else 0 end) as condition4
from department d;
Hope that it would be helpful to you,
Select total,
Sum (Case when total = 100 then NumberOfOrders_Created end ) As "Condition1",
Sum (Case when total > 100 and total <= 200 then NumberOfOrders_Created end ) As "Condition2",
Sum (Case when total > 200 and total <= 300 then NumberOfOrders_Created end ) As "Condition3",
Sum (Case when total > 200 and total <= 300 then NumberOfOrders_Created end ) As "Condition4",
From Department
where
Orders_date between '2013-01-01 00:00:00' and '2013-12-31 00:00:00'
group by 2
order by 1 Desc