I am trying to extract dates which are 2 days after the current date, unless in the case that two days after the current date would be a weekend, in which case I am lookig for dates that are 4 days after the current date. I am using Data Studio and none of the sql functions (like dateadd) work on it.
I know I can get the dates I want using this pull:
select event_end_date from mdmins11.contract where event_end_date between (current date +1.9 days) and (current date + 2.1 days);
But this does not exclude the weekends. I was trying to do it mathematically as such:
select event_end_date
case(
when (current date + 2 days) = ('2014-09-06' + (7 days * int)) or ('2014-09-07' + (7 days * int))
then set #w = (current date + 4 days)
else set #w = (current date + 2 days)
)
from mdmins11.contract where event_end_date = #w;
Here I am trying to find the dates that are after Saturdays and Sundays in case (current date + 2) lands on a weekend. This is not working at all. Does anyone have any idea how to do this on sql without using the functions? I appriciate that my date formatting might be wrong but I am finding it hard to see the solution.
I found the answer! For anyone who is in the same situation:
select dayofweek(current date) as day_number,
event_end_date
from mdmins11.contract
where (dayofweek(event_end_date) = 6 /*Friday*/
and date(event_end_date) < current_date + 3 days
and date(event_end_date) >= current_date)
or (dayofweek(event_end_date) in (1,2,3,4,5,7) /*All other days of week*/
and date(event_end_date) < current_date + 2 days
and date(event_end_date) >= current_date)
;
If you happen to have a list of holiday dates, you can also incorporate this in.
Related
I need to generate a list of week end dates based on the first week end date, and between a date range.
For example: I have a week end date of '06/04/2022'. If I enter 06/01/2022-01/01/2023 as my date parameters, I need a list of every seven days beginning on 06/04/2022 through 01/01/2023. The output would look something like this:
Dates
06/04/2022
06/11/2022
06/18/2022
.
.
.
12/24/2022
12/31/2022
Note: the initial week end date is not necessarily always on a Saturday, so it would need to be based on the actual date and not the day of the week.
I have this code which produces every day between two dates, but I need every seven days between two dates, and based on a date field retrieved from another table. I'm stuck on how to get every seven days, or every week from the date.
select (date'2022-06-04' + level - 1) dt
from dual
connect by level <= (date'2023-01-01' - date'2022-06-01' + 1)
Multiply the step size by 7:
SELECT DATE '2022-06-04' + (level - 1) * 7 AS dt
FROM dual
CONNECT BY DATE '2022-06-04' + (level - 1) * 7 <= DATE '2023-01-01'
Or, to make the calculation you are preforming more obvious that you are adding a week, you can use an INTERVAL literal:
SELECT DATE '2022-06-04' + (level - 1) * INTERVAL '7' DAY AS dt
FROM dual
CONNECT BY DATE '2022-06-04' + (level - 1) * INTERVAL '7' DAY <= DATE '2023-01-01'
You could also calculate the number of weeks required in your connect by levels code.
i.e. This would give you the number of rows required
CONNECT BY LEVEL < (DATE2 - DATE1) / 7
Notably the DATE2 - DATE1 code works because Oracle likes to think of things in terms of days. i.e. Sysdate - 1 is just yesterday. Sysdate + 1 is just tomorrow.
Then tack on a + 1 since you probably want to return 1 row in the case it's less than a week
And then doing this
SELECT DATE'2023-01-24' + (LEVEL-1) * 7
FROM DUAL
CONNECT BY LEVEL < ((SYSDATE - DATE'2023-01-24') / 7) + 1
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 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.
Need help figuring out how to determine if the date is the same 'day' as today in teradata. IE, today 12/1/15 Tuesday, same day last year was actually 12/2/2014 Tuesday.
I tried using current_date - INTERVAL'1'Year but it returns 12/1/2014.
You can do this with a bit of math if you can convert your current date's "Day of the week" to a number, and the previous year's "Day of the week" to a number.
In order to do this in Teradata your best bet is to utilize the sys_calendar.calendar table. Specifically the day_of_week column. Although there are other ways to do it.
Furthermore, instead of using CURRENT_DATE - INTERVAL '1' YEAR, it's a good idea to use ADD_MONTHS(CURRENT_DATE, -12) since INTERVAL arithmetic will fail on 2012-02-29 and other Feb 29th leap year dates.
So, putting it together you get what you need with:
SELECT
ADD_MONTHS(CURRENT_DATE, -12)
+
(
(SELECT day_of_week FROM sys_calendar.calendar WHERE calendar_date = CURRENT_DATE)
-
(SELECT day_of_week FROM sys_calendar.calendar WHERE calendar_date = ADD_MONTHS(CURRENT_DATE, -12))
)
This is basically saying: Take the current dates day of week number (3) and subtract from it last years day of week number (2) to get 1. Add that to last year's date and you'll have the same day of the week as current date.
I tested this for all dates between 01/01/2010 and CURRENT_DATE and it worked as expected.
Why don't you simply subtract 52 weeks?
current_date - 364
The SQL below will get you to the abbreviated name for the day of week, it's cumbersome but it works across versions of Teradata.
SELECT CAST(CAST(ADD_MONTHS(CURRENT_DATE, -12) AS DATE FORMAT 'E3') AS CHAR(3)) AS LY_DayOfWeek
, CAST(CAST(CURRENT_DATE) AS DATE FORMAT 'E3') AS CHAR(3)) AS CY_DayOfWeek
Dates are internally represented at integers in Teradata as (Year-1900) * 100000 + (MONTH * 100) + DAY. You may be able to do some creative arithmetic to figure out that 12/1/2015 Tuesday was 12/2/2014 Tuesday last year.
I have an embedded query that I use to pull previous month data. Everything has been working fine until this month (January). My code looks like this:
(MONTH(CURRENT DATE)-1) = MONTH(TSTAMP)
I have it setup this way because I have a timestamp in my data that I base the query off of. This usually works like a charm, but it's not working this month and I think it's because of the new year. How does this function work when dealing with a different year? Is there a way to write it into the query so I don't have to worry about a change in year?
You can do this by using the year, like this:
YEAR(CURRENT DATE) * 12 + MONTH(CURRENT DATE) - 1 = YEAR(TSTAMP) * 12 + MONTH(TSTAMP)
This, in essence, converts the dates into months since time 0 -- so the -1 makes sense.
The proper way to do this is with a range query (one with an exclusive upper-bound, <, too), so that the db is free to us an index if one is available.
The first of the month can be retrieved pretty easily via:
CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
(Subtract the difference in days between the current date and the start of the month)
This gives a wonderful upper-bound condition for the query:
WHERE tStamp < CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
(Get everything before the start of the current month).
However, since we're really only interested in the previous month, we also need to limit the lower bound. Well that's everything since, or on, the start of that month... and since we can already get the start of the current month:
WHERE tStamp >= CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS + 1 MONTH
AND tStamp < CURRENT_DATE - (DAY(CURRENT_DATE) - 1) DAYS
There's a related way to do this, supposing you have a calendar table with appropriate indices. If you have a minimal table with these columns:
calendarDate - DATE
year - INTEGER
month - INTEGER
dayOfMonth - INTEGER
... you can use this table to get the relevant values instead:
WHERE tStamp >= (SELECT calendarDate
FROM calendarTable
WHERE year = YEAR(CURRENT_DATE - 1 MONTH)
AND month = MONTH(CURRENT_DATE - 1 MONTH)
AND dayOfMonth = 1)
AND tStamp < (SELECT calendarDate
FROM calendarTable
WHERE year = YEAR(CURRENT_DATE)
AND month = MONTH(CURRENT_DATE)
AND dayOfMonth = 1)
(there's a couple of different forms of this, but this one looks pretty simple)