SUM and Count in one SQL Query - sql

I have this kind of data
time Members
-------------------------------------------------- -----------
Jun 23 2016 1
Jun 23 2016 1
Jun 23 2016 2
Jun 29 2016 6
Jul 11 2016 3
Jul 11 2016 1
Jul 13 2016 1
I obtained this data using this sql query
SELECT CONVERT (VARCHAR(12), a.registered_time), COUNT(b.member_id) AS Members
FROM b
Inner JOIN a ON b.mirror_id = a.mirror_id
GROUP BY
(a.registered_time) order by a.registered_time
I want to get the sum of total numbers if they are of the same date for exampple the date of June 23 2016 will have total members of 4 and so on. Is it possible to have SUM() FUnction on Count()? How can I do this?

Convert the value to a date and include that in both the select and group by:
SELECT CONVERT(date, a.registered_time) as dte, COUNT(b.member_id) AS Members
FROM b JOIN
a
ON b.mirror_id = a.mirror_id
GROUP BY CONVERT(date, a.registered_time)
ORDER BY CONVERT(date, a.registered_time);

Related

SQL: Find number of active "events" each month

Background
I have an SQL table that contains all events, with each event containing a unique identifier.
As you can see for some IDs the "event" stretches across multiple months. What I'm trying to find is the number of "active events" per month.
For example event ID:342, is active in both the month of Jan and Feb. So it should count towards both Jan and Feb's final count.
Example dataset
ID
Start Date
End Date
342
01 Jan 2022
12 Feb 2022
231
12 Feb 2022
26 Feb 2022
123
20 Jan 2022
10 Apr 2022
Desired output:
Month
Start Date
Jan
2
Feb
3
Mar
1
Apr
1
btw: I'm using Alibaba's ODPS SQL and not MySQL or Postgres. So i appreciate if the solution provided could be SQL system agnostic. Thanks!
Here is an example is MySQL 8, using a recursive CTE to construct the list of months. It would be more efficient to use a Calendar Table.
If you are not using MySQL you will need to modify the syntax of the query.
create table dataset(
ID int, Start_date Date,End_date Date);
insert into dataset values
(342,'2022-01-01','2022-02-12'),
(231,'2022-01-12','2022-02-26'),
(123,'2022-01-20','2022-04-10');
/*
Desired output:
Month Start Date
Jan 2
Feb 3
Mar 1
Apr 1
*/
✓
✓
✓
select
min(month(Start_date)),
max(month(End_date))
from dataset;
min(month(Start_date)) | max(month(End_date))
---------------------: | -------------------:
1 | 4
with recursive m as
(select min(month(Start_date)) mon from dataset
union all
select mon + 1 from m
where mon < (select max(month(End_date)) from dataset)
)
select
mon "month",
count(id) "Count"
from m
left join dataset
on month(Start_date)<= mon
and month(End_date) >= mon
group by mon
order by mon;
month | Count
----: | ----:
1 | 3
2 | 3
3 | 1
4 | 1
db<>fiddle here

Distribute table data to another table using SQL query

Help on how to distribute Default Table into Transaction Table using SQL Server Query if month is not existing on the other side? Please refer on the sample tables below
Default Table
Month
Value
Jan
0
Feb
0
Mar
0
Apr
0
May
0
Transaction Table
Month
Sales
Jan
10
Feb
0
Apr
20
I want to achieve this below results.
Month
Sales
Jan
10
Feb
0
Mar
0
Apr
20
May
0
You can use INSERT...WHERE NOT EXISTS
INSERT INTO Transaction (Month, Sales)
SELECT c.Month, d.Sales
FROM [Default] d
WHERE NOT EXISTS (SELECT 1
FROM Transaction t
WHERE t.Month = d.Month)

Getting calculated percentages within group using SQL

I have a dataset:
Date
June 2011
July 2011
Aug 2011
Sep 2011
Oct 2011
Jan 2012
Feb 2012
Mar 2012
Apr 2013
May 2013
that records down the date registered for each yearly project. (There are no project IDs however)
I would like to add in the additional variable Percentage, which represent the average progress made for that month. (For instance, if the project is registered for 4 months, then each month would progress incrementally by 25 %, (25,50,75,100)), specifically:
Percentage Date
20 June 2011
40 July 2011
60 Aug 2011
80 Sep 2011
100 Oct 2011
33 Jan 2012
66 Feb 2012
100 Mar 2012
50 Apr 2013
100 May 2013
However, my main problem would be that I am unable to know the starting month (period) and ending month (period) for each project for each year.
Are there any functions in SQL to create the calculated percentages in this case? I thought of creating a year variable and further using an indicator to indicate the start/end of the progress, but could not move on further.
Thank you again!
You can try this query.
Getting ROW_NUMBER() by year(dates) on subquery.
then get the percent.
SELECT (FLOOR(CAST(T2.RK AS decimal) * 100/(
SELECT COUNT(1) AS Totle
FROM T
WHERE year(dates) = T2.dates))) [Percentage],
T2.dates as [years],
T2.months as [months]
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY year(dates) ORDER BY dates DESC) AS RK,
year(dates) as dates,
month(dates) as months
FROM T
) AS T2
GROUP BY T2.dates,T2.RK,T2.months
Here is a simple Pseudo sql to get what you want . ?
select Year(date), Month(date) ,
(select sum(Progress_percentage) from dataset b where b.date <=a.date ) as
subquery_percentage
from dataset a
group by Year(date), Month(date)

T-SQL previous year total in next year column

I currently have a table that looks like this:
fscYear ID Days #Invoices AVG
2011 20000807 221 7 27
2012 20000807 403 15 25
2013 20000807 390 14 26
2014 20000807 119 4 23
I would like to include the previous year's AVG in the next year, like so:
fscYear ID Days #Invoices AVG prevAVG
2011 20000807 221 7 27 0
2012 20000807 403 15 25 27
2013 20000807 390 14 26 25
2014 20000807 119 4 23 26
How I can achieve that?
edit the SQL is straightforward,
select * from theTableThatHoldsThedata
Most databases support ANSI standard window functions. You can do this with lag():
select t.*, coalesce(lag(avg) over (order by by fscyear), 0) as prevAVG
from atable t;
This will work in SQL Server 2012+. For earlier versions, you can use a correlated subquery or apply:
select t.*, coalesce(tprev.prevAvg, 0) as prevAvg
from atable t outer apply
(select top 1 t2.Avg as prevAvg
from atable t2
where t2.fscyear < t.fscyear
order by t2.fscyear desc
) tprev;
You can write as:
SELECT Cur.fscYear ,Cur.ID,Cur.Days,Cur.#Invoices,Cur.AVG,
isnull(Prv.AVG,0) AS prevAVG
FROM test AS Cur
LEFT OUTER JOIN test AS Prv
ON Cur.fscYear = Prv.fscYear + 1;
Demo

oracle pivot query suggestion

I have a simple table that has data like the following
FiscalYear Month Value
2013 01 10
2013 02 15
....
2014 01 15
2014 02 20
using Oracle(11g) Pivot query is it possible to get something like this?
Month 2013 2014
01 10 15
02 15 20
SELECT month, value_2013, value_2014
FROM (SELECT fiscalyear, month, value FROM your_table)
PIVOT (SUM (value) AS value
FOR (fiscal_year)
IN ('2013', '2014'))