Essentially, I have a query that is responsible for fetching all records (with specific filters) within the last month. I'm using Oracle's interval keyword and all was working great until today (December 31st, 2009). The code I'm using is
select (sysdate - interval '1' month) from dual
and the error I get it
ORA-01839: date not valid for month specified
How can I use the interval keyword to be compatible with any date? Or if anyone has a better way of approaching the issue, I'm all ears.
Thank you.
try
select add_months(sysdate,-1) from dual
Being pedantic...
The requirements are not quite specified perfectly unambiguously. What does the business mean by "within the last month"? Most people would take that to mean "within the current calendar month" in which case I'd use:
TRUNC(SYSDATE,'MM')
Otherwise, perhaps they want an arbitrary period of 1 month prior to the current date - but then how do you define that? As you've found, INTERVAL '1' MONTH simply subtracts one from the month portion of the date - e.g. 15-JAN-2009 - INTERVAL '1' MONTH returns 15-DEC-1999. For some dates, this results in an invalid date because not all months have the same number of days.
ADD_MONTHS resolves this by returning the last day in the month, e.g. ADD_MONTHS(31-DEC-2009,-1) returns 30-NOV-2009.
Another possibility is that the business actually wants to use an average month period - e.g. 365/12 which is approximately 30.4. They might want you to use SYSDATE-30, although of course twelve iterations of this will only cover 360 days of the year.
Related
im using spotfire software and i have a datetime column like:
DateTime
21/07/2022 12:11:01
21/07/2022 14:32:01
04/12/2022 10:22:01
30/06/2022 16:22:01
how can i created a new calculated column where it instead changes the date to the monday of the week for all values?
many thanks
i can do this in power bi by dropping the time and using the function
Start of Week Monday = 'Data'[DateTime ]+1-WEEKDAY('Data'[DateTime ]-1)
this results in all the values changing to the monday of its given week/month/year
how can i do this in spotfire?
Assuming you have the following functions available to you: DateAdd, DayOfWeek (*)
You could try:
DateAdd("dd",1 - (If(DayOfWeek([original_Date])=0,7,DayOfWeek([original_Date]))),[original_Date])
This resets the date (including the time portion) to the previous Monday.
Initially I had tried the simpler formula:
DateAdd("dd",1 - DayOfWeek([original_Date]),[original_Date])
but Sunday is mapped to a zero, so whenever the original day was a Sunday, it was pushed to the following Monday.
It does depend on your original settings so you may have to play around with the numbers a bit.
(*) depending on what the source of your data is, equivalent functions may be available.
I have an Excel table which contains thousands of incident tickets. Each tickets typically carried over few hours or few days, and I usually calculate the total duration by substracting opening date and time from closing date and time.
However I would like to take into account and not count the out of office hours (night time), week-ends and holidays.
I have therefore created two additional reference tables, one which contains the non-working hours (eg everyday after 7pm until 7am in the morning, saturday and sunday all day, and list of public holidays).
Now I need to find some sort of VB macro that would automatically calculate each ticket "real duration" by removing from the total ticket time any time that would fall under that list.
I had a look around this website and other forums, however I could not find what I am looking for. If someone can help me achieve this, I would be extremely grateful.
Best regards,
Alex
You can use the NETWORKDAYS function to calculate the number of working days in the interval. Actually you seem to be perfectly set up for it: it takes start date, end date and a pointer to a range of holidays. By default it counts all days non-weekend.
For calculating the intraday time, you will need some additional magic. assuming that tickets are only opened and closed in bussines hours, it would look like this:
first_day_hrs := dayend - ticketstart
last_day_hrs := ticketend - daystart
inbeetween_hrs := (NETWORKDAYS(ticketstart, ticketend, rng_holidays) - 2) * (dayend - daystart)
total_hrs := first_day_hrs + inbetween_hrs + last_day_hrs
Of course the names should in reality refer to Excel cells. I recommend using lists and/or names.
I am working on genealogical software that stores its data in SQLite3 format. Everything works fine, except for one minor detail. Not in all cases is the accuracy of the birth or death dates (etc) available to the exact day. So I have the following accuracies:
exact (YYYY-MM-DD)
month (YYYY-MM)
year (YYYY)
year (YYYY+/-5)
year (YYYY+/-10)
year (YYYY+/-50)
decade
century
Now, assuming I store everything in a single column, I end up with a problem. Since SQLite3 has the Julian Day function I was thinking to encode the accuracy in the fractional part of the REAL Julian Day (I don't need the hours anyway). That is fine, but it complicates the way SELECTs work, in fact it means that stuff I could otherwise offload to SQLite3 has to be implemented in application code.
What would be a reasonable method to store the inaccurate dates and be able to query them quickly?
Note: if it matters to anyone answering, the language used is Python, but I am asking in general.
When doing queries on those date values, the most common operation probably is to check whether a date might match another date.
For this, you always need the start and the end of the interval, so it would make sense to store these two values in the DB.
(Call them Start/End or Min/Max or Earliest/Latest or whatever makes sense.)
For example, to find people who might have been born one century ago:
... WHERE '1913-04-16' BETWEEN BirthDateMin AND BirthDateMax
Inequality comparisons can be done with one of the interval boundaries.
For example, to find people who might have been born more than one century ago:
... WHERE BirthDateMin < '1913-04-16'
Just because you're storing date information, doesn't mean that the built-in date type is the right one for you. Your data requirements (date inaccuracy) means that it's probably more accurate and better long-term to do some custom date-handling work, and avoid using the built-in date data types.
Use two columns. One column is the approximate date, as accurate as possible, in SQLite format. The second column is the accuracy of the date in days. If the date is absolutely accurate, the second column is zero. If only the month is known, the date would be mid month and the second column 15 days. Etc. Date comparisons can be done by comparing against the date +/- the accuracy column.
In MySQL I am using
week(date,3)
to get correct values of week grouping.
How to translate this to PL/SQL? I'v tried the following but what about this 3 from week function in mysql?
TRUNC (created_dt, 'IW')
Oracle is using the NLS setting of the database to determinate how the week number should be calculated and therefor there is no need (according to Oracle) for the '3' part pf the MySQL function. I can image that there still should be useful to have this option but this is once again a sign of the fact that Oracle does not fully understand the needs of working outside USA.
Based on your MYSQL statment above, it returns the week of the specified date e.g. 2012-12-07, 3 as the second argument defines that the third day of the week is assumed as Monday...
If you look at this article it says there are 8 ways MYSQL WEEK() function can behave. So you gotta let us know what results you are trying to achieve by looking for MYSQL Week equivalent function in PL/SQL.
In most staright forward manner, MYSQL WEEK(date[mode]) returns the week number for a given date.
From re-reading your question, the only thing I grabbed that you want to achieve the first feature within PL/SQL and so you are looking for an equivalent function.
And with Oracle it gets slightly RAMEN...
W Week of month (1-5) where week 1 starts on the first day of the month and ends on the seventh. It goes on with how the year starts. E.g. 2012 started on a Sunday, ORACLE THINKS.............. that weeks are Sundays to Saturday.
iw Week of year (1-52, 1-53) based on the ISO standard. Hence the weeks do not necessarily start on Sunday.
WW Week of the year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
By default Oracle NLS settings are set to following:
NLS_CALENDAR : Gregorian
NLS_DATE_LANGUAGE: AMERICAN
NLS_TERRITORY: AMERICA
So you can suggest Oracle to follow the calendar by manipulating your query level....
You could something like this:
select trunc('2012-12-07','YY') AS week_number,
to_number(to_char(trunc('2012-12-07','YY')+rownum-1,'D')) AS dayNumber_in_week
from dual connect by level <= 365
where to_char('2012-12-07','IW') = 3
and to_char('2012-12-07','DY') = 'MON';
here is my sample is this correct?
number of months=nms
days=30 days only
sample: nms=30 days count from the date hired
is this correct?
If you want to get exact month between two date. You have to get difference of them. You can use DateDiff function in Dot Net.