count row with total - sql

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

Related

Count average with multiple conditions

I'm trying to create a query which allows to categorize the average percentage for specific data per month.
Here's how my dataset presents itself:
Date
Name
Group
Percent
2022-01-21
name1
gr1
5.2
2022-01-22
name1
gr1
6.1
2022-01-26
name1
gr1
4.9
2022-02-01
name1
gr1
3.2
2022-02-03
name1
gr1
8.1
2022-01-22
name2
gr1
36.1
2022-01-25
name2
gr1
32.1
2022-02-10
name2
gr1
35.8
...
...
...
...
And here's what I want to obtain with my query (based on what I showed of the table):
Month
<=25%
25<_<=50%
50<_<=75%
75<_<=100%
01
1
1
0
0
02
1
1
0
0
...
...
...
...
...
The result needs to:
Be ordered by month
Have the average use for each name counted and categorized
So far I know how to get the average of the Percent value per Name:
SELECT Name,
AVG(Percent)
from `table`
where Group = 'gr1'
group by Name
and how to count iterations of Percent in the categories created for the query:
SELECT EXTRACT(MONTH FROM Date) as Month,
COUNT(CASE WHEN Percent <= 25 AND Group = 'gr1' THEN Name END) `_25`,
COUNT(CASE WHEN Percent > 25 AND Percent <= 50 AND Group = 'gr1' THEN Name END) `_50`,
COUNT(CASE WHEN Percent > 50 AND Percent <= 75 AND Group = 'gr1' THEN Name END) `_75`,
COUNT(CASE WHEN Percent > 75 AND Percent <= 100 AND Group = 'gr1' THEN Name END) `_100`,
FROM `table`
GROUP BY Month
ORDER BY Month
but this counts all iterations of every name where I want the average of those values.
I've been struggling to figure out how to combine the two queries or to create a new one that answers my need.
I'm working with the BigQuery service from Google Cloud
This query produces the needed result, based on your example. So basically this combines your 2 queries using subquery, where the subquery is responsible to calculate AVG grouped by Name, Month and Group, and the outer query is for COUNT and "categorization"
SELECT
Month,
COUNT(CASE
WHEN avg <= 25 THEN Name
END) AS _25,
COUNT(CASE
WHEN avg > 25
AND avg <= 50 THEN Name
END) AS _50,
COUNT(CASE
WHEN avg > 50
AND avg <= 75 THEN Name
END) AS _75,
COUNT(CASE
WHEN avg > 75
AND avg <= 100 THEN Name
END) AS _100
FROM
(
SELECT
EXTRACT(MONTH from Date) AS Month,
Name,
AVG(Percent) AS avg
FROM
table1
GROUP BY Month, Name, Group
HAVING Group = 'gr1'
) AS namegr
GROUP BY Month
This is the result:
Month
_25
_50
_75
_100
1
1
1
0
0
2
1
1
0
0
See also Fiddle (BUT on MySql) - http://sqlfiddle.com/#!9/16c5882/9
You can use this query to Group By Month and each Name
SELECT CONCAT(EXTRACT(MONTH FROM Date), ', ', Name) AS DateAndName,
CASE
WHEN AVG(Percent) <= 25 THEN '1'
ELSE '0'
END AS '<=25%',
CASE
WHEN AVG(Percent) > 25 AND AVG(Percent) <= 50 THEN '1'
ELSE '0'
END AS '25<_<=50%',
CASE
WHEN AVG(Percent) > 50 AND AVG(Percent) <= 75 THEN '1'
ELSE '0'
END AS '50<_<=75%',
CASE
WHEN AVG(Percent) > 75 AND AVG(Percent) <= 100 THEN '1'
ELSE '0'
END AS '75<_<=100%'
from DataTable /*change to your table name*/
group by EXTRACT(MONTH FROM Date), Name
order by DateAndName
It gives the following result:
DateAndName
<=25%
25<_<=50%
50<_<=75%
75<_<=100%
1, name1
1
0
0
0
1, name2
0
1
0
0
2, name1
1
0
0
0
2, name2
0
1
0
0

sum for each customers and create a summary table

I have Table A :
Customer_ID Card_number Amount_of_deals
1 221 100
1 222 350
2 223 200
3 334 700
3 344 650
4 544 1500
I want to create a new table with ranges of the amount and count of customers in each range.
the new table should be :
Range Number_of_customers
0-500 2
500-1000 0
1000-1500 2
How can I create this table?
Thanks in advance
You can use case expression with group by :
select (case when amount >= 0 and amount <= 500 then '0-500'
when amount > 500 and amount <= 1000 then '501-1000'
when amount > 1000 and amount <= 1500 then '1001-1500'
else '1500+'
end) as Range, count(distinct custmore_id) as Number_of_customers
from table t
group by (case when amount >= 0 and amount <= 500 then '0-500'
when amount > 500 and amount <= 1000 then '501-1000'
when amount > 1000 and amount <= 1500 then '1001-1500'
else '1500+'
end);
If you are using SQL Server then you can use apply & use SELECT .. INTO statement :
select range, count(distinct custmore_id) as Number_of_customers
into new_table
from table t cross apply
( values (case when amount >= 0 and amount <= 500 then '0-500'
when amount > 500 and amount <= 1000 then '501-1000'
when amount > 1000 and amount <= 1500 then '1001-1500'
else '1500+'
end)
) tt(range)
group by range;
Because you want 0 values, you need a left join somewhere. I would recommend:
select v.range, count(c.customer_id)
from (values ('0-500', 0, 500),
('501-1000', 500, 1000),
('1001-1500', 1000, 1500)
) v(range, lo, hi) left join
(select customer_id, sum(amount_of_deals) as num
from a
group by customer_id
) c
on c.num > v.lo and c.num <= v.hi
group by v.range
order by min( v.lo );
Here is a db<>fiddle.

find percentage of sale and percentage of returns

I have a table in MS SQL DB which contains transactions of any company, there are two columns
sub_cat_code
total_amount
The total_amount contain sometimes positive and sometimes negative value. Where positive values indicates the sale and negative value indicates Returns.
Now, I need to find the percentage of sales and percentage of return using following query, in percentage of return column every value coming same. any help would be appreciable.
Select prod_subcat_code ,
(sum(total_amt)*100 /(select sum(total_amt) from transection)) as
Sale_pers,
((select sum(total_amt) from transection where total_amt<0)*100/(select
sum(total_amt) from transection)) as return_sale
from transection
group by prod_subcat_code
order by Sale_pers desc
Use a CTE which returns the total sales and total returns of the table:
with cte as (
select
sum(case when total_amount > 0 then total_amount else 0 end) total_sales,
sum(case when total_amount < 0 then total_amount else 0 end) total_returns
from transection
)
select prod_subcat_code ,
100.0 * sum(case when total_amount > 0 then total_amount else 0 end) / (select total_sales from cte) as sale_perc,
100.0 * sum(case when total_amount < 0 then total_amount else 0 end) / (select total_returns from cte) as return_perc
from transection
group by prod_subcat_code
See the demo.
If I understand correctly, you just want to divide two aggregated values:
Select prod_subcat_code,
sum(total_amt) as net_sales,
sum(case when total_amt > 0 then total_amt else 0 end) as sales,
sum(case when total_amt < 0 then total_amt else 0 end) as returns,
(sum(case when total_amt > 0 then total_amt else 0 end) /
nullif(sum(total_amt), 0)
) as sales_ratio,
(sum(case when total_amt < 0 then total_amt else 0 end) /
nullif(sum(total_amt), 0)
) as return_ratio
from transection
group by prod_subcat_code;
You may want change your query to this for desired result:
Select prod_subcat_code,
sum(case when total_amt > 0 then total_amt else 0 end) as sales,
(sum(case when total_amt > 0 then total_amt else 0 end) /
(sum(total_amt)) ) * 100 as sales_Percent,
sum(case when total_amt < 0 then total_amt else 0 end) as [returns],
(sum(case when total_amt < 0 then total_amt else 0 end) /
(sum(total_amt)) ) * 100 as Return_Percent
from transection
group by prod_subcat_code
order by sales_Percent desc
Hope it will help you,
SELECT prod_subcat_code
,(SUM(CASE WHEN total_amt > 0 THEN total_amt END)/sum(total_amt))*100 AS Sales_Percentage
,(SUM(CASE WHEN total_amt < 0 THEN total_amt END)/sum(total_amt))*100 AS Return_Percentage
FROM transection
GROUP BY prod_subcat_code;

infuse a sum of the value in the another column with a different filter than the total count column

First here's a sample table.
enter image description here
Provider_name patient date status length
AF AGUIR00001 07/05/2018 3 30
AF ABBOT00001 07/05/2018 30
BB ADAMS00001 07/05/2018 3 30
BB ACEVE00001 07/06/2018 3 30
I have created a query that lets me count the total number of appointments versus the number of appointments with a certain status(eg checked out). I was able to create it and group it by provider.
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout
from appointment
group by provider_name
Then I moved on to the next phase which was to get the total length of those appointments with checkedout status. I made this query but it does not break down into each provider.
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
(select sum(length) from appointment where status = 3
and date between '06/01/2018' and '07/06/2018')
from appointment where date between '06/01/2018' and '07/06/2018'
group by provider_name
I need it so that the last column in the query is segregated per provider_name.
Thank you in advance for helping me out.
Actually, you were on the right way, try this:
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
sum(case when status = 3 then length else 0 end) as len_status3
from appointment
where date between '2018-01-06' and '2018-06-07'
group by provider_name;
According to your last comment, you need a WITH ROLLUP modifier for GROUP BY as in the following :
select coalesce(provider_name,'Total') as provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
sum(case when status = 3 then length else 0 end) as len_status3
from appointment
where date between '2018-01-06' and '2018-06-07'
group by provider_name with rollup;
SQL Fiddle Demo
you shoul do as for checkedoutout
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
sum( case when status = 3 then length else 0 ) as total_length
from appointment where date between '06/01/2018' and '07/06/2018'
group by provider_name

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.