I'm trying to make a query dynamic that looks for all the dates between two days of the year (July 1 of the last year and June 30th of this year). Below is the where clause of the query I've been attempting:
and pbh.batch_date between
('30-JUN-'||extract(year from trunc(sysdate))-1))
and ('01-JUL-'||extract(year from trunc(sysdate))))
This returns an inconsistent datatypes error: expected DATE got NUMBER. I then tried casting them to dates like so:
and pbh.batch_date between
to_date(( '01-JUL-'||extract(year from trunc(sysdate))-1))
and to_date(( '30-JUN-'||extract(year from trunc(sysdate))))
But this now returns an invalid number error. I don't know if it makes a difference what format pbh.batch_date is stored as, but it's (m)m/(d)d/yyyy
There's no need to cast to a string and back:
and ph.batch_date >= add_months(trunc(sysdate,'YEAR'), -6)
and ph.batch_date < add_months(trunc(sysdate,'YEAR'), 6)
Related
I am trying to get transaction count month to date. For now I am providing date between from_date and to_date.
How can I get results for a particular month in month to date ?
You don't mention what SQL your using, but if its SQL Server then it has a built in function DatePart description I'd expect most of the major SQL dialects to have something similar.
So your where clause would be something like where datepart(mm, to_date) = 4 (for April)
If your version SQL doesn't have the date functions, then you can fallback to the cruder string manipulation. Assuming your date is yyyymmdd, then you could use a sub string function to pull out the mm part, convert that to a integer and perform your comparison.
Produce a list of films which have a date of release before August 2016.
Hello trying to produce the following SQL query above with this:
SELECT *
FROM FILM
WHERE DATE_OF_RELEASE < '2016-08-01';
but I cannot seem to figure out why I am getting errors?
Trying to answer this as well: Write a SQL statement to count the number of films in the database released before August 2016.
SELECT COUNT(*) AS "Number of films released before August 2016 "
FROM FILM;
WHERE date_of_release < date '2016-08-01';
however get this error:
Error starting at line : 18 in command -
WHERE date_of_release < date '2016-08-01'
Error report -
Unknown Command
Don't do it the wrong way - do it the right way.
If DATE_OF_RELEASE column's datatype is DATE (it should be), then compare it to DATE, not a string. '01-aug-16' or '2016-08-01' are strings, not dates. Don't rely on Oracle and its capabilities to implicitly convert them to dates, because sooner or later it'll fail, as soon as NLS settings change.
So, use
where date_of_release < date '2016-08-01' -- date literal
or
where date_of_release < to_date('01.08.2016', 'dd.mm.yyyy') -- TO_DATE function
Leave strings alone.
Try this
SELECT * FROM FILM WHERE DATE_OF_RELEASE < '01-AUG-16';
I'm trying to exclude results in my query that start in the same month between two columns. For example, I need to exclude benefits1 that start in the same month as benefits2. Format for benefit1_start_date and benefit2_start_date is: YYYYMMDD.
This is what I have so far:
where (benefit1_start_date = (to_char(sysdate, 'YYYYMM') || '0122')) <>
(benefit2_start_date = (to_char(sysdate, 'YYYYMM') || '0122'));
If anyone could put me in the right direction, I'd greatly appreciate it!
Convert your numeric dates to text, and then compare the year and month substrings:
WHERE
SUBSTR(TO_CHAR(benefits1_start_date), 1, 6) <> SUBSTR(TO_CHAR(benefits2_start_date), 1, 6)
Note that storing your dates as numbers like this is atypical, and you might want to consider storing them as dates. If you don't have a day component, you could just use the first as a placeholder.
As I understand it, you want to eliminate records where your 2 columns benefits1_start_date and benefits2_start_date are in the same month, and both have a format of YYYYMMDD.
Are they stored as strings? If so, all you need to do is compare the first 6 characters (if you need to consider yr + month), or just the 5+6th characters if you want to check just the month without the year.
Year + Month:
SUBSTR(benefits1_start_date,1,6) <> SUBSTR(benefits2_start_date,1,6)
Just month:
SUBSTR(benefits1_start_date,5,2) <> SUBSTR(benefits2_start_date,5,2)
If they're not stored as strings but as dates, then you can TRUNC the date to month and compare (for yr + month), or convert the date to MM string via to_char and compare if you just want to check the month.
Hope this helps.
I suggest you to use BETWEEN clause. Converting LEFT side operand to string by function and then making comparison can have severe performance impacts.
if you convert indexed table.dateColumn to string by to_char(table.dateColumn), oracle cannot use defined index on column anymore.
Your desired query:
where to_char(benefit1_start_date, 'YYYYMM') != to_char(benefit2_start_date, 'YYYYMM')
but
select * from table1
where months_between(benefit1_start_date, benefit2_start_date) not between -1 and 1
would be what you are looking for. (no performance impact)
I know how to select the first day of the first month of the current year in a number of different formats. The following works fine: '01-JAN-' || TO_CHAR(TO_DATE(SYSDATE),'YYYY').
However, I need to use January 1, of the current year in a date range criteria in a YTD PSoft Query:
WHERE A.effdt BETWEEN (January 1, Current_Year) AND SYSDATE.
When I use the expression '01-JAN-' || TO_CHAR(TO_DATE(SYSDATE),'YYYY') in the criteria, I get the following error:
A SQL error occurred. Please consult your system log for details.
Error in running query because of SQL Error, Code=1858, Message=ORA-01858:
a non-numeric character was found where a numeric was expected (50,380)`
You should NEVER compare LITERAL with DATE. Since, Oracle will do an IMPLICIT conversion. And, sooner or later, it would become a performance issue.
Explicitly convert the literal to date using TO_DATE.
For example,
Depending on the date value input method,
1. If you are passing the literal via some program
BETWEEN TO_DATE('01-01-2014','DD-MM-YYYY') and SYSDATE
2. If you already have the date value in table, then use TRUNC
BETWEEN TRUNC(SYSDATE, 'YYYY') and SYSDATE
I cannot use months_between, only playing with DATEs is allowed, so I got this:
select * from emp
where ((SYSDATE- hiredate)/(365+1/4-1/100+1/400)) >= ((SYSDATE/(365+1/4-1/100+1/400))-20);
I dont understand why i get error in
(SYSDATE/(365+1/4-1/100+1/400))-20
saying it is an invalid datatype "inconsistent datatypes: expected %s got %s" when
(SYSDATE-hiredate)/(365+1/4-1/100+1/400)
is working properly with no error, WTF?
PS: an example of using (365+1/4-1/100+1/400) is with birth date, for more precision:
((SYSDATE- birth_date)/(365+1/4-1/100+1/400)) >=18
sysdate retuns the current date and time.
In your second test case as below, you are subtracting two dates which returns
numeric value indicating the number of days between the two dates and so calculation (division was made possible).
(SYSDATE-hiredate)/(365+1/4-1/100+1/400)
In your first test case as below, you are directly trying to divide a date type value.
you cannot divide a date datatype in oracle. Instead you can add any value say x (sysdate +x), it means you are adding x days to the date value.
(SYSDATE/(365+1/4-1/100+1/400))-5
In case, you want to convert the sysdate to number you can try like below
select to_number(to_char(sysdate, 'yyyymmddhh24miss')) from dual;
Which will return you DATE+TIME like 20140608165750 for today.
(OR)
select to_number(to_char(sysdate, 'yyyymmdd')) from dual;
Result will be 20140608 (only the DATE part)
According to Oracle on subtracting two Date datatypes you'll get a Number datatype.
From Oracle docs: Reference
So this part of your query
((SYSDATE- birth_date)/(365+1/4-1/100+1/400)) >=18 returns a number, whereas
In this statement (SYSDATE/(365+1/4-1/100+1/400))-5 sysdate is still taken as a date dataype which is why you're getting the error. You can explicitly use to_number to convert sysdate into number.
Edit: Try this ((to_number(to_char(SYSDATE,'DDMMYYYY'))/(365+1/4-1/100+1/400))-5) to convert your sysdate date dataype into number datatype. So, your select query should look like this
select * from emp
where ((SYSDATE- hiredate)/(365+1/4-1/100+1/400)) >= ((to_number(to_char(SYSDATE,'DDMMYYYY'))/(365+1/4-1/100+1/400))-5);