Convert SQL Server code to Oracle please? - sql

Having a bit of a issue with a SQL conversion from SQL Server to Oracle.
We are passing in a datetime value (in this example just 1900-01-01) and we need to select all rows that have a modified date greater than 2 days before the date passsed in. Here is the SQL syntax that works:
SELECT *
FROM TABLENAME
WHERE CAST(LAST_MODIFIED AS DATE) > CAST(DATEADD(dd, -2, '1990-01-01') AS DATE);
Where LAST_MODIFIED is a column, and the '1900-01-01' is a value being injected to the SQL String in C# prior to it being executed. Before being asked, we prefer not to subtract the 2 days from the date before passing it to the SQL :)
So what we need then is just the above query converted to Oracle syntax... We have tried a couple things and it fails :(
Thanks,
Dave

You can write this in Oracle as:
SELECT *
FROM TABLENAME
WHERE TRUNC(LAST_MODIFIED) > (DATE '1990-01-01') - 2
Notes:
In Oracle, DATE includes a time component, so casting to a date does nothing.
Oracle supports various ways to include a date/time constant. I prefer the keyword DATE with the ISO/ANSI standard date format YYYY-MM-DD.
The - 2 is perhaps more accurately written as - interval '2' day. However, the interval notation is new(ish) to Oracle.
And, it is better in either database to write this without modifying last_modified_date:
SELECT *
FROM TABLENAME
WHERE LAST_MODIFIED >= (DATE '1990-01-01') - 1
Removing the time component is not needed, with the right date comparison.

SELECT *
FROM TABLENAME
WHERE CAST(LAST_MODIFIED AS DATE) > TO_DATE('1990-01-01','YYYY-MM-DD')-2;

SELECT *
FROM TABLENAME
WHERE TRUNC( LAST_MODIFIED ) > TO_DATE( '1990-01-01', 'YYYY-MM-DD' ) - 2;
or, if you pass the value in using the :date_value bind variable:
SELECT *
FROM TABLENAME
WHERE TRUNC( LAST_MODIFIED ) > :date_value - 2;
If the value you are passing in to the query does not have a time component then you can just do:
SELECT *
FROM TABLENAME
WHERE LAST_MODIFIED >= :date_value - 1;

Related

How to extract data of last week from Firebird database?

I am having trouble of getting the query working, the database is a Firebird database, and the tool I use for querying the data is DBeaver. - work requirement, no other choice.
The goal is run the query and only pull the data of last week, here is one of the queries I have tried:
select *
from table 1
where 1.payment_rundate > dateadd(DAY, -7,CURRENT_TIMESTAMP())
I find that dateadd syntax is not recognized in DBeaver.
The problem isn't DATEADD, the problem is that the Firebird syntax doesn't allow CURRENT_TIMESTAMP(), it only allows CURRENT_TIMESTAMP (no parentheses) or CURRENT_TIMESTAMP(precision) where precision is 0 - 3.
In other words, use the condition:
payment_rundate > dateadd(DAY, -7, CURRENT_TIMESTAMP)
Part of the problem is that DBeaver's autocompletion generates CURRENT_TIMESTAMP() and positions the cursor inside the parentheses, expecting you to enter the desired precision. If you don't want to specify precision, it is up to you to delete those parentheses.
I would try with interval
select *
from table 1
where 1.payment_rundate between (current_date - INTERVAL 7 DAY) and current_date
I think just the below will do the trick :
select *
from table 1
where 1.payment_rundate >= current_date - 6
if payment_rundate is a timestamp then you can go with that :
select *
from table 1
where cast(1.payment_rundate as date) >= current_date - 6

Converting date format number to date and taking difference in SQL

I have a data set as below,
Same is date in "YYYYMMDD" format, I wanted to convert the columns to date format and take the difference between the same.
I used to below code
SELECT to_date(statement_date_key::text, 'yyyymmdd') AS statement_date,
to_date(paid_date_key::text, 'yyyymmdd') AS paid_date,
statement_date - paid_date AS Diff_in_days
FROM Table
WHERE Diff_in_days >= 90
;
Idea is to convert both the columns to dates, take the difference between them and filter cases where difference in days is more than 90.
Later I was informed that server is supported by HiveSQL and does not support of using ":", date time, and temp tables can not be created.
I'm currently stuck on how to go about given the constraints.
Help would be much appreciated.
Sample date for reference is provided in the link
dbfiddle
Hive is a little convoluted in its use of dates. You can use unix_timestamp() and work from there:
SELECT datediff(to_date(unix_timestamp(cast(statement_date_key as varchar(10)), 'yyyyMMdd')),
to_date(unix_timestamp(cast(paid_date_key as varchar(10)), 'yyyyMMdd'))
) as diff_in_days
FROM Table;
Note that you need to use a subquery if you want to use diff_in_days in a where clause.
Also, if you have date keys, then presumably you also have a calendar table, which should make this much simpler.
Hello You Can Use Below Query It Work Well
select * from (
select convert(date, statement_date_key) AS statement_date,
convert(date, paid_date) AS paid_date,
datediff(D, convert(date, statement_date_key), convert(date, paid_date)) as Diff_in_days
from Table
) qry
where Diff_in_days >= 90
Simple way: Function unix_timestamp(string, pattern) converts string in given format to seconds passed from unix epoch, calculate difference in seconds then divide by (60*60*24) to get difference in days.
select * from
(
select t.*,
(unix_timestamp(string(paid_date_key), 'yyyyMMdd') -
unix_timestamp(string(statement_date_key), 'yyyyMMdd'))/86400 as Diff_in_days
from Table t
) t
where Diff_in_days>=90
You may want to add abs() if the difference can be negative.
One more method using regexp_replace:
select * from
(
select t.*,
datediff(date(regexp_replace(string(paid_date_key), '(\\d{4})(\\d{2})(\\d{2})','$1-$2-$3')),
date(regexp_replace(string(statement_date_key), '(\\d{4})(\\d{2})(\\d{2})','$1-$2-$3'))) as Diff_in_days
from Table t
) t
where Diff_in_days>=90

Convert YYYYMMDD String to Date in Impala

I'm using SQL in Impala to write this query. I'm trying to convert a date string, stored in YYYYMMDD format, into a date format for the purposes of running a query like this:
SELECT datadate,
session_info
FROM database
WHERE datadate >= NOW() - INTERVAL 5 DAY
ORDER BY datadate DESC;
Since the >= NOW() - INTERVAL 5 DAY code won't work with the YYYYMMDD string, I'd like to find a way to convert that into a date format that will work with this type of query. My thought is that it should look something like this (based on similar questions about other SQL query editors), but it's not working in Impala:
SELECT datadate,
session_info,
convert(datetime, '20141008', 102) AS session_date
FROM database
WHERE session_date >= NOW() - INTERVAL 5 DAY
ORDER BY session_date DESC;
Anyone know how to do this in Impala?
EDIT:
I finally found a working solution to the problem. None of the attempts using configurations of CAST or CONVERT would work in Impala, but the below query solves the problem and is fully operational, allowing date math to be performed on a column containing string values:
SELECT datadate,
session_info
FROM database
WHERE datadate >= from_unixtime(unix_timestamp(now() - interval 5 days), 'yyyyMMdd')
GROUP BY datadate
ORDER BY datadate DESC;
Native way:
to_timestamp(cast(date_number AS STRING), 'yyyyMMdd')
See Timestamp Literals on [Link Updated 2020-08-24]:
https://docs.cloudera.com/cdp-private-cloud-base/7.1.3/impala-sql-reference/topics/impala-literals.html
You need to add the dashes to your string so Impala will be able to convert it into a date/timestamp. You can do that with something like:
concat_ws('-', substr(datadate,1,4), substr(datadate,5,2), substr(datadate,7) )
which you can use instead of datadate in your expression.
To ignore hour/minute/second... , use from_timestamp, result 2020-01-01.
select from_timestamp(cast('2020-01-01 01:01:01.000000' as TIMESTAMP),'yyyy-MM-dd');

YYYYMMDD to YYYYMM in oracle

I have a column with DATE datatype in a table.
I am trying to retrieve the column values in YYYYMM format. My select query looks like below
select *
from tablename
where date column = to_char(to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
I am getting below exception.
ORA-01847: day of month must be between 1 and last day of month
Appreciate any input on this.
I think the simplest method is:
where to_char(datecolumn, 'YYYYMM') = '400012'
Or, if you prefer:
where to_char(datecolumn, 'YYYYMM') = to_char(to_date('12/31/4000', 'MM/DD/YYYY'), 'YYYYMM');
Syntax-wise, the right hand date (to the right of the equals) is OK. But you are doing a character comparison, not a date comparison.
This works for me in multiple databases:
select to_char (to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM')
from dual;
Even though your column is named DATE_COLUMN, you are comparing based on characters in the query.
So, try this instead - this compares based on dates (NOT a character comparison) and truncates off the hour, minute, ETC. so you are only comparing the DAY:
select * from DATE_TAB
where TRUNC(DATE1, 'DDD') = TRUNC(to_date('12/31/4000','MM/DD/YYYY'),'DDD');
NOTE: The DATE1 field above is a DATE field. If you're DATE_COLUMN is not a DATE field, you must
convert it to a DATE datatype first (using TO_DATE, ETC.)
Assuming that "date_column" is actually a date, and that you have an index on date_column, you can do something like this to return the data quickly (without truncating dates in all rows to do a comparison):
with dat as (
select level as id, sysdate - (level*10) as date_column
from dual
connect by level <= 100
)
select id, date_column
from dat
where date_column between to_date('11/1/2013', 'MM/DD/YYYY') and last_day(to_date('11/2013 23:59:59', 'MM/YYYY HH24:MI:SS'))
Here I just dummy up some data with dates going back a few years. This example picks all rows that have a date in the month of November 2013.
If your date_column's data-type is DATE, then use
select *
from tablename
where TO_CHAR(date_column,'YYYYMM') = to_char (to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
If your date_column's data-type is VARCHAR, then use:
select *
from tablename
where date_column = to_char (to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
I somehow feel your error is because you have a space between date and column as
"date column". If the field name in the table is "COLUMN", then just removing the word "DATE" from your original query would suffice, as:
select *
from tablename
where column = to_char(to_date('12/31/4000','MM/DD/YYYY'),'YYYYMM');
If your column (YYYYMMDD) is in number format, the simplest way to get YYYYMM would be
select floor(DATE/100)
from tablename;

Select from table by knowing only date without time (ORACLE)

I'm trying to retrieve records from table by knowing the date in column contains date and time.
Suppose I have table called t1 which contains only two column name and date respectively.
The data stored in column date like this 8/3/2010 12:34:20 PM.
I want to retrieve this record by this query for example (note I don't put the time):
Select * From t1 Where date="8/3/2010"
This query give me nothing !
How can I retrieve date by knowing only date without the time?
DATE is a reserved keyword in Oracle, so I'm using column-name your_date instead.
If you have an index on your_date, I would use
WHERE your_date >= TO_DATE('2010-08-03', 'YYYY-MM-DD')
AND your_date < TO_DATE('2010-08-04', 'YYYY-MM-DD')
or BETWEEN:
WHERE your_date BETWEEN TO_DATE('2010-08-03', 'YYYY-MM-DD')
AND TO_DATE('2010-08-03 23:59:59', 'YYYY-MM-DD HH24:MI:SS')
If there is no index or if there are not too many records
WHERE TRUNC(your_date) = TO_DATE('2010-08-03', 'YYYY-MM-DD')
should be sufficient. TRUNC without parameter removes hours, minutes and seconds from a DATE.
If performance really matters, consider putting a Function Based Index on that column:
CREATE INDEX trunc_date_idx ON t1(TRUNC(your_date));
Personally, I usually go with:
select *
from t1
where date between trunc( :somedate ) -- 00:00:00
and trunc( :somedate ) + .99999 -- 23:59:59
Convert your date column to the correct format and compare:
SELECT * From my_table WHERE to_char(my_table.my_date_col,'MM/dd/yyyy') = '8/3/2010'
This part
to_char(my_table.my_date_col,'MM/dd/yyyy')
Will result in string '8/3/2010'
You could use the between function to get all records between 2010-08-03 00:00:00:000 AND 2010-08-03 23:59:59:000
trunc(my_date,'DD') will give you just the date and not the time in Oracle.
Simply use this one:
select * from t1 where to_date(date_column)='8/3/2010'
Try the following way.
Select * from t1 where date(col_name)="8/3/2010"