How can I get a query displayed monthly with a subquery - sql

I have a query here with a subquery. This shows me the complete result for the year. How do I get it to be displayed to me on a monthly basis. I've tried a few things but always get an error message
Here my query
SELECT
masch_nr, SUM(dauer) AS Prozess_Verfügbarkeit,
(SELECT SUM(dauer)
FROM [hydra1].[hydadm].[ereignis]
WHERE YEAR(begin_ts) = YEAR(CURRENT_TIMESTAMP)
AND masch_nr = 'FIMI1'
AND bmktonr IN ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11')) AS Verfügbarkeit
FROM
[hydra1].[hydadm].[ereignis]
WHERE
YEAR(begin_ts) = YEAR(CURRENT_TIMESTAMP)
AND masch_nr = 'FIMI1'
AND bmktonr IN ('7', '11')
GROUP BY
masch_nr
The result should look like this:
Month | Prozess_Verfügbarkeit | Verfügbarkeit
------+-----------------------+--------------
1 | 344 | 4556
2 | 445 | 5654
Thank you

You can probably simplify this by using conditional aggregation
SELECT
YEAR(begin_ts) AS [Year]
, MONTH(begin_ts) AS [Month]
, masch_nr
, SUM(CASE WHEN bmktonr IN ('7', '11')
THEN dauer END) AS Prozess_Verfügbarkeit
, SUM(CASE WHEN bmktonr IN ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11')
THEN dauer END) AS Verfügbarkeit
FROM [hydra1].[hydadm].[ereignis]
WHERE masch_nr = 'FIMI1'
AND begin_ts >= DATEADD(YEAR,DATEDIFF(YEAR,0,CURRENT_TIMESTAMP),0)
AND begin_ts < DATEADD(YEAR,DATEDIFF(YEAR,0,CURRENT_TIMESTAMP)+1,0)
GROUP BY YEAR(begin_ts), MONTH(begin_ts), masch_nr
ORDER BY [Year], [Month], masch_nr

Related

Include 0 in a COUNT() in Hive

I have a table of users and medications and want to return the count of all meds by user even if the count is 0. The result would have columns for user, med, and count, and 9 users x 9 meds = 81 key rows.
user = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
med = ['acyclovir' ,'azathioprine' ,'basiliximab' ,'bevacizumab' ,'carboplatin','ciprofloxacin_dexamethasone_otic' ,'cisplatin' ,'clofarabine', 'cyclophosphamide']
I tried:
SELECT user, med, COUNT(*)
FROM db.table
WHERE user IN ('1', '2', '3', '4', '5', '6', '7', '8', '9')
AND med IN ('acyclovir' ,'azathioprine' ,'basiliximab' ,'bevacizumab' ,'carboplatin','ciprofloxacin_dexamethasone_otic' ,'cisplatin' ,'clofarabine','cyclophosphamide')
GROUP BY user, med
ORDER BY user ASC
However, this only returned count for meds by user with COUNT(*) > 0. How can I change it to return all counts?
As far as I understand, you need to get a count of med given to a user, if none, then show 0.
Here is the qry you can use.
SELECT user,
SUM(case when med IN ('acyclovir' ,'azathioprine' ,'basiliximab' ,'bevacizumab' ,'carboplatin','ciprofloxacin_dexamethasone_otic' ,'cisplatin' ,'clofarabine','cyclophosphamide') then 1 else 0 end ) as med_count
--this will give you count of medicine taken by user. If 0 then the count will be 0. But its difficult to show the name of medicine.
FROM db.table
WHERE user IN ('1', '2', '3', '4', '5', '6', '7', '8', '9')
GROUP BY user
ORDER BY user ASC
Edit : could you please try this sql. It will give you med count of an user. If med isnt in the list it will show 0.
SELECT user,
SUM(case when med IN ('acyclovir' ,'azathioprine' ,'basiliximab' ,'bevacizumab' ,'carboplatin','ciprofloxacin_dexamethasone_otic' ,'cisplatin' ,'clofarabine','cyclophosphamide') then 1 else 0 end ) as med_count,
--this will give you count of medicine taken by user. If not in listed med then the count will be 0.
case when med IN ('acyclovir' ,'azathioprine' ,'basiliximab' ,'bevacizumab' ,'carboplatin','ciprofloxacin_dexamethasone_otic' ,'cisplatin' ,'clofarabine','cyclophosphamide') then med else null end as med
FROM db.table
WHERE user IN ('1', '2', '3', '4', '5', '6', '7', '8', '9')
GROUP BY user ,case when med IN ('acyclovir' ,'azathioprine' ,'basiliximab' ,'bevacizumab' ,'carboplatin','ciprofloxacin_dexamethasone_otic' ,'cisplatin' ,'clofarabine','cyclophosphamide') then med else null end
ORDER BY user ASC

fetching startdate and enddate from timestemp column and partition by modes in SQL

i am trying to solve this this is table1 and i am trying to have below output i am not able to build up a logic that how could i fetch start date and end date from same timestemp column in SQL.
CREATE TABLE table1 (
`batch` INTEGER,
`timestemp` VARCHAR(8),
`mo` INTEGER,
`speed` INTEGER
);
INSERT INTO table1
(`batch`, `timestemp`, `mo`, `speed`)
VALUES
('1', '00:18:00', '0', '0'),
('1', '01:18:00', '0', '0'),
('1', '02:18:00', '0', '0'),
('1', '03:18:00', '1', '5'),
('1', '04:18:00', '1', '6'),
('1', '05:18:00', '1', '7'),
('1', '06:18:00', '2', '10'),
('1', '07:18:00', '2', '9'),
('1', '08:18:00', '2', '8'),
('1', '09:18:00', '3', '12'),
('1', '10:18:00', '3', '23'),
('1', '11:18:00', '3', '21'),
('1', '12:18:00', '4', '20'),
('1', '13:18:00', '4', '22');
mo=mode
batch
timestemp
mo
speed
1
00:18:00
0
0
1
01:18:00
0
0
1
02:18:00
0
0
1
03:18:00
1
5
1
04:18:00
1
6
1
05:18:00
1
7
1
06:18:00
2
10
1
07:18:00
2
9
1
08:18:00
2
8
1
09:18:00
3
12
1
10:18:00
3
23
1
11:18:00
3
21
1
12:18:00
4
20
1
13:18:00
4
22
ooutput:
batch
start time
end time
mode
1
00:18:00
03:17:00
0
1
03:18:00
06:17:00
1
1
06:18:00
09:17:00
2
1
09:18:00
12:17:00
3
1
12:18:00
13:18:00
4
Schema (MySQL v8.0)
CREATE TABLE table1 (
`batch` INTEGER,
`timestemp` TIME,
`mo` INTEGER,
`speed` INTEGER
);
INSERT INTO table1
(`batch`, `timestemp`, `mo`, `speed`)
VALUES
('1', '00:18:00', '0', '0'),
('1', '01:18:00', '0', '0'),
('1', '02:18:00', '0', '0'),
('1', '03:18:00', '1', '5'),
('1', '04:18:00', '1', '6'),
('1', '05:18:00', '1', '7'),
('1', '06:18:00', '2', '10'),
('1', '07:18:00', '2', '9'),
('1', '08:18:00', '2', '8'),
('1', '09:18:00', '3', '12'),
('1', '10:18:00', '3', '23'),
('1', '11:18:00', '3', '21'),
('1', '12:18:00', '4', '20'),
('1', '13:18:00', '4', '22');
Query
SELECT batch
, mode
, start_time
, COALESCE(SUBTIME(LEAD(start_time) OVER (ORDER BY start_time), '00:01:00'), end_time) end_time
FROM (
SELECT batch
, min(timestemp) start_time
, max(timestemp) end_time
, mo mode
FROM table1
GROUP BY batch, mo
) min_max;
batch
mode
start_time
end_time
1
0
00:18:00
03:17:00
1
1
03:18:00
06:17:00
1
2
06:18:00
09:17:00
1
3
09:18:00
12:17:00
1
4
12:18:00
13:18:00
View on DB Fiddle

How to get distinct count for last x weeks data but group by week in redshift?

I have a below query which I run gives me the single count for month as current month and dates_for_week has list of all the dates for last week from Sunday to Saturday.
select COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
AND year = '2020'
-- this is for month october but week 43
and (month = '10' and dates_for_week IN ('18', '19', '20', '21', '22', '23', '24'))
As of now the output I see is this -
Count
-----
982
Now I am trying to make this query dynamic such that it can give me count for past 6 weeks something like below as an output:
Count Week
------------
982 W43
123 W42
126 W41
127 W40
128 W39
129 W38
I am able to convert above query in a dynamic way which gives me the count for current month october and previous week which is 43 and it works fine as shown below but I am not sure how can I change it so that it can give me data for all past 6 weeks in the above output format. It looks like I need to change the month also dynamically for some week to get output for past 6 weeks.
select COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
AND year = '2020'
-- this is for month october but week 43
and (
month = extract(month from current_date)
and dates_for_week IN (
select
date_part('d',((DATE_TRUNC('week', CURRENT_DATE) - 9) + row_number() over (order by true))::date)
from process.data
limit 7
)
)
So what I need is this for last 6 week and group by week to give me the count as shown above. Is this possible to do by any chance?
and (month = '10' and dates_for_week IN ('18', '19', '20', '21', '22', '23', '24'))
and (month = '10' and dates_for_week IN ('11', '12', '13', '14', '15', '16', '17'))
and (month = '10' and dates_for_week IN ('4', '5', '6', '7', '8', '9', '10'))
and (month IN ('9', '10') and dates_for_week IN ('27', '28', '29', '30', '1', '2', '3'))
and (month = '9' and dates_for_week IN ('20', '21', '22', '23', '24', '25', '26'))
and (month = '9' and dates_for_week IN ('13', '14', '15', '16', '17', '18', '19'))
You have years, months and days in seperate columns if I understand it correctly. I think the easiest way is to "build" a proper date column and then working with this column.
The following query should give you the last 6 weeks including the current week.
select
EXTRACT(week from TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD')) week_num
,COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
and TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD') >= DATEADD(day,-42,DATE_TRUNC('week', sysdate))
GROUP BY 1
ORDER BY 1 desc
However, there might be a challenge as weeks start on a Monday in redshift, so might need to do a slight manipulation (adding one day):
select
EXTRACT(week from DATEADD(day,1,TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD'))) week_num
,COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
and DATEADD(day,1,TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD')) BETWEEN DATEADD(day,-42,DATE_TRUNC('week', sysdate)) AND DATEADD(day,-1,DATE_TRUNC('week', sysdate))
GROUP BY 1
ORDER BY 1 desc
Debugging:
I would start running this query first, to check if the date is calculated properly
select COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
AND year = '2020'
-- this is for month october but week 43
and TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD') between '2020-10-18' and '2020-10-24'
Afterwards I would see if the week is calculated correctly:
select
EXTRACT(week from DATEADD(day,1,TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD'))) week_num
,COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
AND year = '2020'
-- this is for month october but week 43
and TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD') between '2020-10-18' and '2020-10-24'
group by 1
order by 1
And last but not least I would extend the timeframe and make it dynamic:
select
EXTRACT(week from DATEADD(day,1,TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD'))) week_num
,COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
AND year = '2020'
-- this is for month october but week 43
and DATEADD(day,1,TO_DATE(year||'-'||month||'-'|| dates_for_week,'YYYY-MM-DD')) Between DATEADD(day,-42,DATE_TRUNC('week', sysdate)) and DATEADD(day,-1,DATE_TRUNC('week', sysdate))
group by 1
order by 1
Assuming that you have some kind of date column, you can simply use something like this
select date_part(w, {your_date_column) as week_number,
COUNT(DISTINCT(CLIENTID))
FROM process.data
where type = 'pots'
and stype= 'kites'
and tires IN ('abc', 'def', 'ghi', 'jkl')
and comp IN ('data', 'hello', 'world')
AND year = '2020'
group by 1
You could use order by and limit:
select year, week, COUNT(DISTINCT CLIENTID)
from process.data
where type = 'pots' and
stype= 'kites' and
tires IN ('abc', 'def', 'ghi', 'jkl') and
comp IN ('data', 'hello', 'world')
group by year, dates_for_week
order by year desc, week desc
limit 6;
This is assuming that you have a week column, which seems like a reasonable assumption.
This is a simple way to accomplish what you want to do. I am guessing that on Redshift it should have decent performance.

SQL - Help needed with this query - Table A and Table B joining two tables and not lose data counts

---Table A:
CREATE TABLE TABLE_A (
BadgeNum varchar(10), --This is a persons unique number.
Gender varchar(2), ---Gender 'F' or 'M'
Date_Sent date, --- Date of Questionnaire
Type_Status varchar(3), --- A person can be Single or Married
Living_State varchar(2), --Person's living state
S_Type_Type int , -- Value can be 1 or 0
Recipient_num int, --Key to create grouping to put each person in category. Using Case Statement for this 'Billing_Transaction' or 'Online_Transaction'
MONTH,
YEAR
);
-- Table B:
CREATE TABLE TABLE_B
(
BadgeNumber varchar, --- This is a persons unique number
RespondedYear smalldate, --- Year a person responded
RespondedMonth smalldate, --- Month a person responded
Date_Process -- This is in YYMMWW (Year,Month,Week)
Value money, --- Cost of the purchase
State --- Person's resides
)
----Sample Data for TABLE_A---
INSERT INTO TABLE_A
VALUES ('11E2', 'F', '07/20/2020', 'Single', 'NV' , '1' , '00001', '07', '2020');
VALUES ('11E3', 'M', '06/30/2020', 'Married', 'AZ' , '1' , '00001', '06', '2020');
VALUES ('11E4', 'F', '05/22/2019', 'Single', 'TN', '1' , '00001', '05', '2019');
VALUES ('11E5', 'M', '05/30/2018', 'Married', 'NY' , '1' , '00001', '05', '2018' );
VALUES ('11E6', 'F', '03/25/2017', 'Single', 'CA' , '1' , '00001', '03', '2017');
VALUES ('11E7', 'M', '02/27/2017', 'Married', 'VT' , '1' , '00002', '02', '2017');
VALUES ('11E8', 'F', '03/01/2018', 'Single', 'AL', '1' , '00002', '03', '2018');
VALUES ('11E2', 'F', '07/20/2020', 'Single', 'NV' , '1' , '00001', '07', '2020');
VALUES ('11E3', 'M', '06/30/2020', 'Married', 'AZ' , '1' , '00001', '06', '2020');
VALUES ('11E4', 'F', '05/22/2019', 'Single', 'TN', '1' , '00001', '05', '2019');
VALUES ('11E5', 'M', '05/30/2018', 'Married', 'NY' , '1' , '00001', '05', '2018' );
VALUES ('11E6', 'F', '03/25/2017', 'Single', 'CA' , '1' , '00001', '03', '2017');
VALUES ('11E7', 'M', '02/27/2017', 'Married', 'VT' , '1' , '00002', '02', '2017');
VALUES ('11E8', 'F', '03/01/2018', 'Single', 'AL', '1' , '00002', '03', '2018');
---SampleDate for TABLE_B
INSERT INTO TABLE_B
VALUES ('11E3', '2020', '7', '200208', '200', 'AZ' );
VALUES ('11E2', '2018', '5', '180520', '300', 'NV' );
VALUES ('11E4', '2018', '3', '180311', '200', 'TN' ) ;
VALUES ('11E5', '2020', '6', '200416', '800', 'NY' );
VALUES ('11E6', '2019', ' 5', '191250', '500', 'CA' );
VALUES ('11E7', '2018', '3', '180313', '100', 'VT' );
VALUES ('11E8', '2019', ' 5', '191251', '1000', 'AL' );
----Queries for Table A---
SELECT
MOnth,
Year,
BadgeNum,
Gender,
Date_Sent,
Type_Status,
Living_State,
S_Type_Type,
,CASE WHEN Recipient_num IN ('00001') THEN 'Billing_Transaction'
WHEN Recipient_num IN ('00002') THEN 'Online_Transaction'
END as [Category]
,COUNT(DISTINCT case when [S_Type_Type] = '1' THEN 'BadgeNum' ELSE NULL END) as [Sent_Questions]
,COUNT([BadgeNum]) as [NumberOfBadges]
FROM [TABLE_A]
GROUP bY
MOnth,
Year,
BadgeNum,
Gender,
Date_Sent,
Type_Status,
Living_State,
S_Type_Type,
--- Queries for Table B----
Table B-
=========
SELECT
COUNT([BadgeNumber]) as [Total_Number_Answered] ,
RespondedYear,
RespondedMonth,
Date_Process,
Value,
State
FROM TABLE_B
GROUP BY
RespondedYear,
RespondedMonth,
Date_Process,
Value,
State
---- Output From Two Table:
Result of the TABLE_A
===================
YEAR MONTH Sent_Questions
===== ======= =====================
2017 03 2
2017 02 0
2018 03 0
2018 05 2
2019 05 2
2020 07 2
2020 06 2
Result of the TABLE_B
========================
YEAR MONTH Total_Number_Answered
===== ======= =====================
2017 03 0
2017 02 0
2018 03 1
2018 05 1
2019 05 2
2020 07 1
2020 06 1
---This is the result I need -----
Expected Result:
==============================
YEAR MONTH Total_Number_Answered Sent_Questions
===== ======= ===================== ===============
2017 03 0 2
2017 02 0 0
2018 03 1 0
2018 05 1 2
2019 05 2 2
2020 07 1 2
2020 06 1 2
Here is the query that I am stuck on: I want to get the same numbers as the Expected Result table. I would like to join Table A and Table B with the Year and Month in some fashion without losing any data. I am having trouble with it.
Here is the query that I have started to work with:
SELECT
MOnth,
Year,
BadgeNum,
Gender,
Date_Sent,
Type_Status,
Living_State,
S_Type_Type,
,CASE WHEN Recipient_num IN ('00001') THEN 'Billing_Transaction'
WHEN Recipient_num IN ('00002') THEN 'Online_Transaction'
END as [Category]
,COUNT(DISTINCT case when [S_Type_Type] = '1' THEN 'BadgeNum' ELSE NULL END) as [Sent_Questions]
,COUNT([BadgeNum]) as [NumberOfBadges]
t2.[Counts_Display]
FROM [TABLE_A] as t1
FULL OUTER JOIN
(
SELECT
COUNT ([BadgeNumber]) as [Counts_Display]
,LEFT([RespondedYear],4)+LEFT([RespondedMonth],2) as [CombinedDates]
,VALUE
,State
) as t2
ON (t2.[BadgeNumber] = t1.[BadgeNum])
and t2.[RespondedYear] = t1.[Year]
and t1.[RespondedMonth] = t2.[Month]
GROUP bY
MOnth,
Year,
BadgeNum,
Gender,
Date_Sent,
Type_Status,
Living_State,
S_Type_Type,
t2.[Counts_Display]

Rolling 12 month Sum in PostgreSQL

I need to be able to create a Trailing Twelve Month report using SQL (PostgreSQL) - essentially a window/rolling 12 month sum that sums up the current month's totals + the previous 11 months for each month.
I have this table:
CREATE TABLE order_test(
order_id text,
sale_date date,
delivery_date date,
customer_id text,
vendor_id text,
order_total float);
with these values:
insert into order_test
values ('1', '2016-06-01', '2016-06-10', '2', '3', 200.10),
('2', '2016-06-02', '2016-06-11', '2', '4', 150.50),
('3', '2016-07-02', '2016-07-11', '5', '4', 100.50),
('4', '2016-07-02', '2016-07-11', '1', '4', 150.50),
('5', '2016-07-02', '2016-07-11', '1', '4', 150.50),
('6', '2016-08-02', '2016-08-11', '6', '4', 300.50),
('7', '2016-08-02', '2016-08-11', '6', '4', 150.50),
('8', '2016-09-02', '2016-09-11', '1', '4', 150.50),
('9', '2016-10-02', '2016-10-11', '1', '4', 150.50),
('10', '2016-11-02', '2016-11-11', '1', '4', 150.50),
('11', '2016-12-02', '2016-12-11', '6', '4', 150.50),
('12', '2017-01-02', '2017-01-11', '7', '4', 150.50),
('13', '2017-01-02', '2017-01-11', '1', '4', 150.50),
('14', '2017-01-02', '2017-01-11', '1', '4', 100.50),
('15', '2017-02-02', '2017-02-11', '1', '4', 150.50),
('16', '2017-02-02', '2017-02-11', '1', '4', 150.50),
('17', '2017-03-02', '2017-03-11', '2', '4', 150.50),
('18', '2017-03-02', '2017-03-11', '2', '4', 150.50),
('19', '2017-04-02', '2017-04-11', '6', '4', 120.50),
('20', '2017-05-02', '2017-05-11', '1', '4', 150.50),
('21', '2017-06-02', '2017-06-11', '2', '4', 150.50),
('22', '2017-06-02', '2017-06-11', '1', '4', 130.50),
('23', '2017-07-02', '2017-07-11', '1', '4', 150.50),
('24', '2017-07-02', '2017-07-11', '5', '4', 200.50),
('25', '2017-08-02', '2017-08-11', '1', '4', 150.50),
('26', '2017-09-02', '2017-09-11', '2', '4', 100.50),
('27', '2017-09-02', '2017-10-11', '1', '4', 150.50);
These are individual sales. For each month, I need the previous 11 months + that month's total (sale month).
I've tried a window calculation like this:
select date_trunc('month', sale_date) as sale_month,
sum(order_total) over w as total_sales
from order_test
where (delivery_date < current_date) and
(sale_date >= (date_trunc('month', current_date) - interval '1 year'))
window w as (Partition by date_trunc('month', sale_date)
order by sale_date
rows between current row and 11 following)
but it's giving me this:
sale_month total_sales
1 01.09.2016 00:00:00 150,5
2 01.10.2016 00:00:00 150,5
3 01.11.2016 00:00:00 150,5
4 01.12.2016 00:00:00 150,5
5 01.01.2017 00:00:00 401,5
6 01.01.2017 00:00:00 251
7 01.01.2017 00:00:00 100,5
8 01.02.2017 00:00:00 301
9 01.02.2017 00:00:00 150,5
10 01.03.2017 00:00:00 301
11 01.03.2017 00:00:00 150,5
12 01.04.2017 00:00:00 120,5
13 01.05.2017 00:00:00 150,5
14 01.06.2017 00:00:00 281
15 01.06.2017 00:00:00 130,5
16 01.07.2017 00:00:00 351
17 01.07.2017 00:00:00 200,5
18 01.08.2017 00:00:00 150,5
19 01.09.2017 00:00:00 100,5
where there should only be one row per month.
In inner query derived table, you need to truncate Sale_Date column to month precision using date_trunc and group by the resulting column to get the Month_total sales and then in outer query, use cumulative window sum function on month_total sales data ordering by Sale_Month to get your desired result as below.
SELECT sale_Month
,month_total
,sum(month_total) OVER (
ORDER BY sale_Month ASC rows BETWEEN 11 preceding
AND CURRENT row
) AS Sum_Series
FROM (
SELECT date_trunc('month', Sale_Date) AS Sale_Month
,sum(Order_Total) AS Month_Total
FROM order_test
GROUP BY 1
ORDER BY 1
) t
Kindly note that AND CURRENT row is optional as cumulative window function includes the current row by default, so the query can be rewritten as below.
SELECT sale_Month
,month_total
,sum(month_total) OVER (
ORDER BY sale_Month ASC rows 11 preceding
) AS Sum_Series
FROM (
SELECT date_trunc('month', Sale_Date) AS Sale_Month
,sum(Order_Total) AS Month_Total
FROM order_test
GROUP BY 1
ORDER BY 1
) t
Result:
sale_month month_total sum_series
----------------------------------------------
2016-06-01T00:00:00Z 350.6 350.6
2016-07-01T00:00:00Z 401.5 752.1
2016-08-01T00:00:00Z 451 1203.1
2016-09-01T00:00:00Z 150.5 1353.6
2016-10-01T00:00:00Z 150.5 1504.1
2016-11-01T00:00:00Z 150.5 1654.6
2016-12-01T00:00:00Z 150.5 1805.1
2017-01-01T00:00:00Z 401.5 2206.6
2017-02-01T00:00:00Z 301 2507.6
2017-03-01T00:00:00Z 301 2808.6
2017-04-01T00:00:00Z 120.5 2929.1
2017-05-01T00:00:00Z 150.5 3079.6
2017-06-01T00:00:00Z 281 3010
2017-07-01T00:00:00Z 351 2959.5
2017-08-01T00:00:00Z 150.5 2659
2017-09-01T00:00:00Z 251 2759.5
You can check the demo here
If I understand it correctly, you want all months to have cumulative data for the last 11 months. But the first 11 rows won't have preceding 11 entries to calculate the rolling sum. But you have mentioned that all months should have a cumulative total.
So I believe you are looking for something like this.
with x as (
select date_trunc('month', sale_date) as sale_month,sum(order_total) as monthly_order_total from order_test
group by 1 order by 1 asc)
select sale_month, monthly_order_total,
sum(monthly_order_total ) over (order by sale_month asc rows between 11 preceding and current row)
from x