calculate the end of months between two dates in dax - ssas

I want to calculate the end of months between two dates. For example, if I start with 2019/11/1 and end with 2020/6/30
I want : 30/11 , 30/12,........, 30/6
I wrote
EndofCurrentMonth = EOMONTH(testdates[LastDateCurrentYear],1)
EndofCurrentMonth = EOMONTH(testdates[LastDateCurrentYear],1)
please any help ??
I wrote also this code : but it gives an error
Datesbetween( CALENDAR (DATE(2019,12,1), DATE(2019,11,31))
,testdates[FirstDayCYR],testdates[EndofCurrentMonth])
The cube is already done, I want to build a report using power bi report builder , and I want to compare the sales in the end of the month and make it dynamically, my year begins on 1 NOV

This should work:
FILTER (
CALENDAR ( DATE ( 2019, 11, 1 ), DATE ( 2020, 6, 30 ) ),
EOMONTH ( [Date], 0 ) = [Date]
)

Related

Calculate current quarter Fiscal_start date based off 13 week (91 day) rolling quarters

I am looking for a SQL solution to work in Oracle Developer SQL that will calculate the current quarters start and end date based off of sysdate and that the Fiscal calendar starts on Feb 1, 2020. Each quarter is a Fixed 13 weeks (91 days) -- NOT 3 months, therefore each year has a slightly different fiscal calendar.
Code will be uploaded to automated reporting and do not want to adjust it each year.
Current year fiscal calendar attached as sample explanation.
Current Fiscal Calendar
I started to head down this road but got lost when i realized the start date wasnt able to be correct in this format.
End solution would be used for a where clause to determine reporting date range such as
( Where Report_Date between Modified_Quarter_Start and sysdate )
select trunc(add_months(add_months(trunc(sysdate,'Y') -1 ,
to_number(to_char(sysdate,'Q')) * 3),-1),'MM')
start_date,trunc(add_months(add_months(trunc(sysdate,'Y') -1 ,
to_number(to_char(sysdate,'Q')) * 3),+2),'MM')-1 Endd_date,
add_months(trunc(sysdate,'Y') -1 ,to_number(to_char(sysdate,'Q')) * 3) end_date ,
to_char(sysdate,'YYYY - q') qtr from dual
Greatly appreciate any assistance.
Posting incase someone else runs into the same predicement in the future.
After reading a mention of a case statement for fixed days in another thread, i thought of this solution.
Select Trunc(sysdate - to_date('02-Feb-2019')),
Case When Trunc(sysdate - to_date('02-Feb-2019')) > 91 Then to_date('02-Feb-2019') +
Round( to_number(Trunc(sysdate - to_date('02-Feb-2019'))/91),0) * 91
Else null End Current_Quarter_Start,
Case When Trunc(sysdate - to_date('02-Feb-2019')) > 91 Then to_date('02-Feb-2019') +
( (Round( to_number(Trunc(sysdate - to_date('02-Feb-2019'))/91),0) +1 )* 91)-1 Else null End Current_Quarter_End From Dual

I'm trying to calculate variance using sql between two same days of two years

I will try to be simple as possible to make my question crystal-clear. I have a table that's called 'fb_ads' (it's about different facebook compaigns for different stores in USA) on BigQuery, it contains the following columns:
STORE : name of store
CLICKS: number of clicks.
IMPRESSIONS: number of impressions of the ad
COST: the ad cost
DATE: AAAA-MM-DD
Frequency: number of visitors of a store
So, I'm trying to calculate the variance between two years 2017 and 2018.
Here is the variance I'm trying to calculate:
Variance_Of_Frequency = ((Frequency in 2018 at date X) - ((Frequency in 2017 at date X))/((Frequency in 2017 at date X)
The problem is, that I'll have to compare the same day of the week close to Date X;
For example, if I have a compaign run on a Monday 2017-08-13, I'll need to compare to another monday in 2018 close to 2018-08-13 (it might be a monday on 2018-08-15 for example).
This is a daily variance!
I tried to make a weekly variance calculating and I don't know if it's correct, here is how I did it:
I first started with aggregating my daily table to a weekly tables using the following query:
creating my weekly_table
SELECT
year_week,
STORE,
min(DATE ) as DATE ,
SUM(IMPRESSIONS ) AS FB_IMPRESSIONS ,
SUM(CLICKS ) AS FB_CLICKS ,
SUM(COST) AS FB_COST ,
SUM(Frequency) AS FREQUENCY,
FROM (
SELECT
*,
CONCAT(cast(ANNEE as string), LPAD(cast((extract(WEEK from date)) as string), 2, '0') ) AS year_week
FROM `fb_ads`)
GROUP BY
year_week,
STORE,
ORDER BY year_week
Then I tried to calculate the variance using this:
SELECT
base.*, (base.frequency-lw.frequency) / lw.frequency as VAR_FF
FROM
`weekly_table` base
JOIN (
SELECT
* EXCEPT (date),
DATE_ADD(DATE(TIMESTAMP(date)) , INTERVAL 1 Week)AS date
FROM
`weekly_table` ) lw
ON
base.date = lw.date
AND base.store= lw.store
Anyone has any idea how to do the daily thing or if my weekly queries are correct ?
Thanks!
For a given date, you want to know the date of the nearest Monday to the same date in the following year...
SET #dt = '2017-08-17';
SELECT CASE WHEN WEEKDAY(#dt + INTERVAL 1 YEAR) > 3
THEN ADDDATE(ADDDATE(#dt + INTERVAL 1 YEAR,INTERVAL 1 WEEK),INTERVAL - WEEKDAY(#dt + INTERVAL 1 YEAR) DAY)
ELSE ADDDATE(#dt + INTERVAL 1 YEAR,INTERVAL - WEEKDAY(#dt + INTERVAL 1 YEAR) DAY)
END x;
Obviously, I could remove all those + INTERVAL 1 YEAR bits by defining #dt that way to begin with.

Adjusting dates and adding new rows

I am trying to calculate the difference between dates but in order to separate them out correctly by month I am hoping to add new rows instead of have a column for each month. I need the following:
If the month of a start date [ss_strt_dtd] equal the month of the end date [ss_end_dtd] then nothing needs to happen.
However, if the the months differ then I need the start date to remain the same but the end date to be the first date of the new month. Then a new start date in the first of the month and the end date to remain the same.
Example:
January 15, 2018 - January 18, 2018 - Nothing needs to happen
January 28, 2018 - February 2, 2018 would need to be split into two
rows that look like this:
[ss_strt_dtd]01/28/2018 [ss_end_dtd]02/01/2018
[ss_strt_dtd]02/01/2018 [ss_end_dtd]02/02/2018
Any thoughts would be appreciated!
You can use UNION:
select ss_strt_dtd, ss_end_dtd from [S&S_Combined]
where year(ss_strt_dtd) = year(ss_end_dtd) and month(ss_strt_dtd) = month(ss_end_dtd)
union all
select ss_strt_dtd, DateSerial(year(ss_end_dtd), month(ss_end_dtd), 1) from [S&S_Combined]
where year(ss_strt_dtd) <> year(ss_end_dtd) or month(ss_strt_dtd) <> month(ss_end_dtd)
UNION ALL select DateSerial(year(ss_end_dtd), month(ss_end_dtd), 1), ss_end_dtd from [S&S_Combined]
where year(ss_strt_dtd) <> year(ss_end_dtd) or month(ss_strt_dtd) <> month(ss_end_dtd);
You can this with a set of queries that also will work if the timespan covers many months.
First a small query to return 10 numbers:
SELECT DISTINCT Abs([id] Mod 10) AS N
FROM MSysObjects;
Save this as Ten.
Then a query to return a the series of months in your date interval:
PARAMETERS
[DateStart] DateTime,
[DateEnd] DateTime;
SELECT
[Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000 AS Id,
[DateStart] AS DateStart,
[DateEnd] AS DateEnd,
DateAdd("m",[Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000,[DateStart]) AS DateMonth
FROM
Ten AS Ten_0,
Ten AS Ten_1,
Ten AS Ten_2,
Ten AS Ten_3,
Ten AS Ten_4,
Ten AS Ten_5,
Ten AS Ten_6
WHERE
(((DateAdd("m",
[Ten_0].[N]+[Ten_1].[N]*10+[Ten_2].[N]*100+[Ten_3].[N]*1000+[Ten_4].[N]*10000+[Ten_5].[N]*100000+[Ten_6].[N]*1000000,
[DateStart]))<=DateAdd("m",
DateDiff("m", [DateStart],DateAdd("d",-1,[DateEnd])),[DateStart]))
AND ((Ten_0.N)<=DateDiff("m",[DateStart],[DateEnd])\1)
AND ((Ten_1.N)<=DateDiff("m",[DateStart],[DateEnd])\10)
AND ((Ten_2.N)<=DateDiff("m",[DateStart],[DateEnd])\100)
AND ((Ten_3.N)<=DateDiff("m",[DateStart],[DateEnd])\1000)
AND ((Ten_4.N)<=DateDiff("m",[DateStart],[DateEnd])\10000)
AND ((Ten_5.N)<=DateDiff("m",[DateStart],[DateEnd])\100000)
AND ((Ten_6.N)<=DateDiff("m",[DateStart],[DateEnd])\1000000));
Save this as MonthsDateRange.
Finally, calculate the From and To dates for each month respecting the start and end date:
SELECT
MonthsDateRange.Id,
MonthsDateRange.DateStart,
MonthsDateRange.DateEnd,
Year([DateMonth]) AS [Year],
Month([DateMonth]) AS [Month],
IIf(DateDiff("m",[DateStart],[DateMonth])=0,
[DateStart],
DateSerial(Year([DateMonth]),Month([DateMonth]),1)) AS DateFrom,
IIf(DateDiff("m",[DateEnd],[DateMonth])=0,
[DateEnd],
DateSerial(Year([DateMonth]),Month([DateMonth])+1,1)) AS DateTo,
DateDiff("d",[DateFrom],[DateTo]) AS Days
FROM
MonthsDateRange;
Save this as DaysMonthsDateRange.
It will return something like this:
Note, that the query is designed to be able to return the months of the entire range of data type Date.
That is 118800 records from 100-01-01 to 9999-12-31.

Recurring events reminder in SQL

I'm trying to run a simple query to calculate what will be a reminder based upon one date (enrollment_date.) It's a recurring event every 90 days starting with the enrollment date but our staff needs only to see the next possible date. So if one date is in December they will only see that date until it passes and then only see the next after that date has passed. Is that possible? I'm using oracle sql
All that will be seen is:
Until December 12 2015
Client Next Inquiry Date
Client A December 12, 2015
After December 12 2015
Client Next Inquiry Date
Client A March 11 2016
It's not much but this is what I have so far.
SELECT
client_name, enrollment_date,
CASE
WHEN CURRENT_DATE <= DATE(day, 90, nextdue_date)
I think there are still quite a few unknowns with your scenario, but here is an example (for SQL Server) that will show you the next 100 90-day reminders. You can use a CTE to generate a list of reminder dates for each client then use the MIN from that list for each client that is still greater than the current date.
DECLARE #enroll_date DATE = '2015-12-12' --For testing
--DECLARE #enroll_reminder DATE = DATEADD(DAY, 90, #enroll_date)
;WITH cte AS (
SELECT 1 AS count_
UNION ALL
SELECT count_+1
FROM cte
WHERE count_<100
)
SELECT
'Client A'--replace with your column name
,MIN(DATEADD(DAY, 90*count_, #enroll_date)) AS test
FROM cte
--GROUP BY your_column_name
HAVING MIN(DATEADD(DAY, 90*count_, #enroll_date)) > GETDATE()
In this scenario, the next reminder is 2016-03-11, then when that day passes it will show 2016-06-09, then 2016-09-07, etc.
Check if this works for you...
Since this is Oracle (PL/SQL) we cannot use TOP 1 and hence using ROWNUM property.
SELECT client_name as "Client"
, enrollment_date as "Next Inquiry Date"
FROM <table_name>
WHERE enrollment_date < (SYSDATE + 90)
AND ROWNUM = 1
ORDER BY enrollment_date

Createing a report using financial periods

I have created a report for management that will total everything up by month with in a date range. Management has now decided that rather than by month they would like to go by period. We have 13 periods in a year each is 28 days except the last one is 29 or 30 depending on if its a leap year. The beginning of the first period is always 1-1-YYYY. So now I will need to figure out what the beginning and end of each period is and total up each period. I am not really sure how to do this since every year the dates will change and they may want to look at periods from the previous year through the current period. The code and results I am currently using are enclosed
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, finspecteddate), 0) AS 'Date'
,COUNT(*) AS Lots
,sum(flotSize) as 'Lot Size'
,sum(LReject) 'Lots Rejected'
,sum(fnumreject) as Rejected
,sum(fsampleSize) as 'Sample Size'
,sum(BDueDate) as 'Before Due Date'
FROM
ReportData
WHERE
finspecteddate >= '01-01-2014'
AND finspecteddate <= '10-15-2014'
GROUP BY
DATEADD(MONTH, DATEDIFF(MONTH, 0, finspecteddate), 0)
ORDER BY
date
Modify the following queries to suit your needs:
;WITH Period AS (
SELECT 1 AS ReportingPeriod,
CAST('2013-01-01' AS datetime) AS PeriodStartDate,
CAST('2013-01-28' AS datetime) AS PeriodEndDate
UNION ALL
SELECT CASE
WHEN p.ReportingPeriod = 13 THEN 1
ELSE p.ReportingPeriod + 1
END,
CASE
WHEN p.ReportingPeriod = 13 THEN DATEADD(YEAR,YEAR(p.PeriodStartDate)-1899,'1900-01-01')
ELSE DATEADD(DAY,28,p.PeriodStartDate)
END,
CASE
WHEN p.ReportingPeriod = 12 THEN DATEADD(YEAR,YEAR(p.PeriodStartDate)-1900,'1900-12-31')
ELSE DATEADD(DAY,28,p.PeriodEndDate)
END
FROM Period p
WHERE p.PeriodStartDate < '2017-12-03'
)
SELECT
P.PeriodStartDate
,P.PeriodEndDate
,COUNT(*) AS Lots
,sum(flotSize) as 'Lot Size'
,sum(LReject) 'Lots Rejected'
,sum(fnumreject) as Rejected
,sum(fsampleSize) as 'Sample Size'
,sum(BDueDate) as 'Before Due Date'
FROM
ReportData R
INNER JOIN Period P ON R.finspecteddate >= P.PeriodStartDate AND R.finspecteddate <= P.PeriodEndDate
WHERE
finspecteddate >= '01-01-2014'
AND finspecteddate <= '10-15-2014'
GROUP BY
P.PeriodStartDate
,P.PeriodEndDate
ORDER BY
P.PeriodStartDate
It uses a recursive CTE to build a period table, which is then joined to ReportData to aggregate asccording to your requirements. I don't have SQL Server 2005 to test it on. It works with 2008. Post a SQL Fiddle if you need help in 2005.
If you haven't got one, create a period calendar table with a year, period number, start date and end date columns. Then when you need to refer to periods, you can refer to the table. When they change the definition of what a period is, you can change the table. When they decide that February 29 doesn't count as one of the 28 days, you can change the table. When they decide to use the first Monday instead of the first Thursday as the start of the year, you just change the table. And best of all, changing how next year works won't change how last year works.
Then you just join to the table to determine which period you're in.