Oracle SQL: Dynamic timeframe calculation - sql

Greetings all knowing Stack.
I am in a bit of a pickle, and I am hoping for some friendly assistance form the hive mind.
I need to write a query that returns the difference in days between a registration date (stored in a table column) and the first day of the last September.
For example; assuming the query was being run today (24-10-2016) for a record with a registration date of 14-07-2010, I would want the script to return the difference in days between 14-07-2010 and 01-09-2016
However had I run the same query before the end of last August, for example on 12-08-2016, I would want the script to return the difference in days between 14-07-2010 and 01-09-2015.
I'm fine with the process of calculating differences between dates, it's just the process of getting the query to return the 'first day of the last September' into the calculation that is tripping me up!
Any input provided would be much appreciated.
Thankyou =)

Try this approach:
add four months to the current date
truncate this date to the first of year
subtract four months again
Add_Months(Trunc(Add_Months(SYSDATE, 4), 'year'), -4)

Hope this might help.
WITH T AS (SELECT TO_DATE('14-07-2010','DD-MM-YYYY') REG_DATE,
SYSDATE EXEC_DATE
FROM DUAL)
SELECT CASE WHEN TO_CHAR(EXEC_DATE,'MM') >= 9
THEN ADD_MONTHS(TRUNC(EXEC_DATE,'YEAR'),8)
ELSE ADD_MONTHS(TRUNC(ADD_MONTHS(EXEC_DATE,-12),'YEAR'),8)
END
- REG_DATE AS DIFF
FROM T;

Related

Oracle Months Between does not work properly

Good morning,
I've wrote the following query to get the months difference between a date column (STRT_DT) and a timestamp column (VLD_FRM_TMS) stored in two different tables.
I don't know why it works for some records but does not for others (it calculates one month less)
select ID, floor (months_between (cast(a.VLD_FRM_TMS as date), STRT_DT)) as delta
from TABLE_A a
inner join TABLE_B b
on a.ID = b.ID
This is an example of record for which the calculation does not work:
VLD_FRM_TMS
-----------
28-FEB-21 12.00.00.000000000 AM
STRT_DT
--------
29-OCT-20
The formula calculates 3 months instead of 4...
Could anyone help me in locating the problem?
Thank you in advance
This is exactly the behavior that is described in the documentation:
If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer. Otherwise Oracle Database calculates the fractional portion of the result based on a 31-day month and considers the difference in time components date1 and date2.
(Note: Highlighting is mine.)
If you run this code:
select months_between(date '2021-02-28', date '2020-10-29') as delta
from dual
The result is 3.9677.
I suspect that you want some other logic. However, the question does not specify what logic you actually do want.
I actually want the months difference regardless of the specific day of the month.
You can truncate both values to the first of the month using the 'MM' format element, and then get the difference between those:
months_between (trunc(a.VLD_FRM_TMS, 'MM'), trunc(STRT_DT, 'MM')) as delta
That will now always be an integer - i.e. a whole number of months - so you don't need to trunc/floor/round the result.
db<>fiddle showing the problem with the old calculation and this version.

datepart in sql on year change

I am using datepart function in SP. It is used to compare week and year of specified date.
Now my query arise as new year starts. I have one table called 'Task' and it is storing tasks date wise. Now When I execute SP with DATEPART(YY,'2016-01-05') . It is giving proper 2016's data. But I execute it with DATEPART(ISOWK,'2016-01-05') , it is giving 2015's data also with 2016's data.
I want data from 28th dec,2015 to 2nd jan,2016. Data of the week. And I am not able get data of 1st and 2nd Jan in that. Please help me with this.
Thanks,
ISOWK return the week number
You are trying to get date from 2015-12-28 to 2016-01-02.
The week number of 2015-12-28 is 53 and 2016-01-02 is 53
If you already have your start and end dates decided then you could use a simple query as shown below to filter on date range.
When mentioning date string in your query make sure you stick to this format :yyyymmdd which SQL Server will automatically understand. You don't need DATEPART to get records between two dates.
Query for filtering on a date range
SELECT TaskID, TaskDescription
FROM Tasks
where TaskDate between '20151228' and '20160102'
Another query you can use for date range filtering
SELECT TaskID, TaskDescription
FROM Tasks
where TaskDate >= '20151228' and TaskDate <= '20160102'

Get the month and year now then count the number of rows that are older then 12 months in SQL/Classic ASP

I know this one is pretty easy but I've always had a nightmare when it comes to comparing dates in SQL please can someone help me out with this, thanks.
I need to get the month and year of now then compare it to a date stored in a DB.
Time Format in the DB:
2015-08-17 11:10:14.000
I need to compare the month and year with now and if its > 12 months old I will increment a count. I just need the number of rows where this argument is true.
I assume you have a datetime field.
You can use the DATEDIFF function, which takes the kind of "crossed boundaries", the start date and the end date.
Your boundary is the month because you are only interested in year and month, not days, so you can use the month macro.
Your start time is the value stored in the table's row.
Your end time is now. You can get system time selecting SYSDATETIME function.
So, assuming your table is called mtable and the datetime object is stored in its date field, you simply have to query:
SELECT COUNT(*) FROM mtable where DATEDIFF(month, mtable.date, (SELECT SYSDATETIME())) > 12

Teradata Change format of Week Number

I'm pretty new to SQL so I hope this isn't a dumb question, tried to google but couldn't find anything.
I'm summing sales of departments per week in SQL and am using TD_SYSFNLIB.WEEKNUMBER_OF_YEAR (trans_dt) to get the week number.
I think everything is working except I'd like to change the format of the weeks to the start date of the week, e.g. week 1 = 1/4/15
Also, i'm not sure how to handle the very first of the year week 0 since I think that should be grouped up with week 52 of last year.
The following date math trick should get you Beginning of Week as an actual date without having to join to the SYS_CALENDAR view or using a function:
SELECT CURRENT_DATE - ((CURRENT_DATE - DATE '0001-01-07) MOD 7) AS BOW;
Starting with TD14 there's NEXT_DAY which returns the following weekday, if you subtract 7 days you get the previous day:
next_day(trans_dt - 7, 'sunday')

How to use conditions in SQLite (like if-statements, etc.)

I have a table in a database with one column containing dates and another one containing scores. Basically, what I want to do is grab the best score in a given week.
Weeks can start on any given day (From Friday to Thursday, for instance), and that is defined by the user.
Here is what I have so far:
SELECT MAX(Series), DATE(DATE(Date, 'weekday 0'), '-7 days') dateStartOfWeek FROM SeriesScores
WHERE Season = '2010-2011'
AND dateStartOfWeek = '2010-08-29'
GROUP BY DateStartOfWeek
Where Series is the column containing the scores and Date is the (badly) named actual date.
The problem with this query is that it works for every day except for the day the week is supposed to be starting on.
For example: 2010-08-29 is a Sunday and in this example, I'm trying to find on which date the Sunday of the given week is. My function works for every day of that week except for 2010-08-29 (Sunday) since it tries to find the next day that is a Sunday (itself in this case). To compensate for that, I go back 7 days to get the correct Sunday, which creates the error for the already correct Sunday since this one doesn't need to go back 7 days or else it is one week off.
I figured I could solve this problem easily using Java, but I want to see how it should be done using SQL instead.
My solution (I don't even know if it can be done), would be to check if date and dateStartOfWeek are the same. If they are, don't substract 7 days from the date. If they're not, do as I did in my example. I don't know how to use conditions such as this one in SQL, though, and this is where I need help.
Thanks a lot in advance!
I think you need to use CASE operator - see http://sqlite.awardspace.info/syntax/sqlitepg09.htm
EDIT - try:
SELECT MAX(Series), CASE WHEN STRFTIME ( '%w', Date ) = 0 THEN DATE(Date, 'weekday 0') ELSE DATE(DATE(Date, 'weekday 0'), '-7 days') END AS dateStartOfWeek FROM SeriesScores
WHERE Season = '2010-2011'
AND dateStartOfWeek = '2010-08-29'
GROUP BY DateStartOfWeek
see http://www.sqlite.org/lang_datefunc.html