Oracle query BETWEEN (date) AND (date) - sql

My table "Message" contain a column name : message_date (datatype : TIMESTAMP) which stores date and time. But in this case, I would like to only show the date of the data, so I use the method to_char(case(message_date as date),'DD-MM-YYYY')
SELECT msg_id, msg_details, to_char(cast(message_date as date) ,'DD-MM-YYYY')as "DATE"
FROM message
WHERE message LIKE '%hi%'
AND to_char(cast(message_date as date), 'DD-MM-YYYY')
BETWEEN '15-01-2018'
AND '30-01-2018'
I would like to show only the row between the date 15-01-2018 and 30-01-2018. But in the end, the query result came out with the data which from date 15 - 30..where row with other month (exp: 20-03-2018 also shown in the result. I not sure why it only check for the date and not together with month and year...
Seek for help ..thanks

Use date literals with the dates in an ISO compliant format:
WHERE
message LIKE '%hi%' AND
message_date BETWEEN date '2018-01-15' AND date '2018-01-30'
Notr that you don't need to cast message_date to text, because it is already a timestamp and can be directly compared to dates.

The only issue with using BETWEEN when comparing dates is if one or more of the dates you're comparing has a time portion. For example, the date 30-JAN-18 01.32.32 PM certainly isn't between 15-JAN-18 and 30-JAN-18 - it's greater (er, later) than the latter date. Plus while using BETWEEN, which is inclusive, there is always the chance of including an edge case you didn't intend. My recommendation would be to do something like this:
SELECT msg_id, msg_details, TO_CHAR(message_date, 'DD-MM-YYYY') AS "DATE"
FROM message
WHERE message LIKE '%hi%'
AND message_date >= DATE'2018-01-15'
AND message_date < DATE'2018-01-30' + 1;
Notice in the first line I got rid of your CAST() - there is no reason to cast a date value to the DATE datatype. In the last line I'm using a bit of Oracle date arithmetic; this will give me all dates up to and including 30-JAN-18 11:59.59.9999.....
As an aside you might want to apply the LOWER() function to message in your WHERE clause:
WHERE LOWER(message) LIKE '%hi%'
otherwise you will miss messages containing Hi, HI, hI, etc.

Related

Doesn't displaying date period

I have a problem with filtering date. I have SQL-query which are displayed all required parameters in certain date. I think that I also need create query which will return the same parameters, but with several required date.
Example: now in my query "2020-12-06", "2021-12-06". But I wanna get all data for period "2020-12-06" - "2021-12-06"
I tried create something, but best that I have - displaying for date which set, but not displaying period:
select ledgeraccounttypeid, dateeffective, sum(amount) from ledgertransaction
where ledgeraccounttypeid in (2,1,16) and dateeffective in('2020-12-06', '2021-12-06')
group by ledgeraccounttypeid, dateeffective
*Important: Period will set from program
**I will have: "YYYY.MM.DD" OR "YYYY.MM.DD - YYYY.MM.DD".
Do you want between?
where dateeffective between date '2020-12-06' and date '2021-12-06'
This assumes that dateeffective is of a date-like datatype, as it should be.
In many cases, half-open intervals better fit the needs:
where
dateeffective >= date '2020-12-06'
and dateeffective < date '2021-12-06' + interval '1' day
This syntax would work in both Postgrs and MySQL, also in the latter we would dispense the date keyword to introduce literal dates.

Oracle SQL - convert a varchar2 into a date

I have a problem with converting a varchar2 fields into a date format.
I got 2 columns with the datatyp varchar2, one is called qtime the other is called ztime. Both fields contain strings in this format (f.e. 152015 -> would be a timestamp 15:20:15).
For reporting reasons I need to convert this fields into a date format, afterwards I want to substract (qtime-ztime) the fields an convert them into the format [hh] (f.e. after the operation 01:20:00 would be -> 01). Is it possible to to this within Oracle SQL 12c? The biggest problem for me right now is that I don't get those Strings converted into a date format.
select TO_DATE(qtime,'MM/DD/YYYY hh24:mi:ss') just gives me
ORA-01861:"literal does not match format string"
select TO_DATE(qtime,'hh24mmss') gives me a wrong Date
01.03.2018
select TO_TIMESTAMP(qtime,'hh24mmss') gives me a wrong Date
01.03.2018 BUT the correct time with f.e. 15:20:15,0000000
Thank you in advance, any help is appreciated
Note: I only have reading rights on the database Oracle 12c, so I need to to this within Statements
"The Database contains another column with the correct date for each time"
The missing piece of the puzzle! Concatenate the two columns to get something which can be converted to an Oracle DATE:
select to_date(qdate||qtime, 'yyyymmddhh24miss') as qdatetime
, to_date(zdate||ztime, 'yyyymmddhh24miss') as zdatetime
from your_table
Once you have done that you can perform arithmetic of the dates e.g.
select id
, zdatetime - qdatetime as time_diff
from ( select id
, to_date(qdate||qtime, 'yyyymmddhh24miss') as qdatetime
, to_date(zdate||ztime, 'yyyymmddhh24miss') as zdatetime
from your_table
)
If you want the number of hours in the difference you can include this expression in the projection of the outer query:
, extract( hour from (zdatetime - qdatetime) day to second) as hrs_ela
First off, if you are trying to convert a varchar2 into a date without specifying neither day nor month, it will default to the first day of the current month:
If you specify a date value without a date, then the default date is the first day of the current month.
You can read up more here
Also in 2nd and 3rd your example, you are using 'hh24mmss' for specifying hour, minute and second components, but do note that correct format for minutes is 'mi' and not 'mm', which is used for months.
So the solution is to concatenate both date and time component when creating the date as the other answer suggested, tho I would recommend using a single date field as it can store the information you need.

Remove Time from date field in Teradata

Im trying to remove the time portion of a date field I am pulling in. I am using Teradata. I tried
select cast(inv_dt as date) as invoice
from tablex
to no avail it still is showing 09/01/2015 12:00:00 AM
I dont want to cast it as a char as I need to use the field in a calculation for dates. Thank you.
Your cast(inv_dt as date) does exactly what you want, you can use it in your calculation for dates...
If it's still showing a time portion it's due to your client (maybe it assumes Teradata's DATE is similar to Oracle's including time).
Finally figured it out
select
cast(cast(inv.INV_DT- EXTRACT(DAY FROM inv.INV_DT) + 1 as date format 'mm/dd/yyyy') as char (10)) as inv_dt
from invoice inv

Find record between two dates

When I write below query it gives record .
SELECT [srno],[order_no],[order_date],[supplier_name],[item_code],[item_name],[quntity]
FROM [first].[dbo].[Purchase_Order]
WHERE order_date BETWEEN '22/04/2015' AND '4/05/2015'
In this query if I don't add 0 in '4/05/2015' it returns record.
But when I add 0 to the date i.e. '04/05/2015' it doesn't give any records.
SELECT [srno],[order_no],[order_date],[supplier_name],[item_code],[item_name],[quntity]
FROM [first].[dbo].[Purchase_Order]
WHERE order_date BETWEEN '22/04/2015' AND '04/05/2015'
The reason it's not working because SQL is trying to do a string comparison because both your types are string types, But what you really want to do a date comparison.
You should do something like this. Since you only need date part you can strip off the time and use style 103 for your format dd/mm/yyyy.
WHERE CONVERT(DATETIME,LEFT(order_date,10),103)
BETWEEN CONVERT(DATETIME,'20150422') AND CONVERT(DATETIME,'20150504')
Alternately you can use this as well if your order_date has dates like this 5/4/2015 03:20:24PM
WHERE CONVERT(DATETIME,LEFT(order_Date,CHARINDEX(' ', order_Date) - 1),103)
BETWEEN CONVERT(DATETIME,'20150422') AND CONVERT(DATETIME,'20150504')
A long term solution is to change your column order_date to DATE/DATETIME
It Better to Cast it to date rather than depend on IMPLICIT conversion
SELECT [srno],[order_no],[order_date],[supplier_name],[item_code],
[item_name],[quntity] FROM [first].[dbo].[Purchase_Order] where
convert(date,order_date,105) BETWEEN cast('22/04/2015' as Date) AND cast('04/05/2015' as date)

How to take differece between 2 dates of different format in SQL

I have a table with a LOAD_STRT_DTM colum. This is a date column and values are like this - 18-JUL-14 08.20.34.000000000 AM.
I want to find the data which came before 5 days.
My logic is -
Select * from Table where 24 *(To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY')) >120
The issue is -
Select (To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY')) from table
This query should give the NumberOfDays between two dates. But this is not working, I Doubt, the issue is because of the format of the LOAD_STRT_DTM colum.
Please let me know where i am doint it wrong.
If your column is DATE datatype everything is ok, just shoot an:
select * from table where LOAD_STRT_DTM > sysdate - 5;
No need to convert dates to DATE datatype.
(To_DATE(Sysdate,'DD-MM-YY') - To_DATE(LOAD_STRT_DTM,'DD-MM-YY'))
You don't have to convert a DATE into a DATE again. IT is already a DATE. You just need to use it for date calculations. You use TO_DATE to convert a STRING into a DATE.
For example, if you have a string value like '18-JUL-14', then you would need to convert it into date using TO_DATE. Since your column is DATE data type, you just need to use as it is.
This is a date column
I want to find the data which came before 5 days.
Simply use the filter predicate as:
WHERE load_strt_dtm > SYSDATE - 5;
NOTE : SYSDATE has both date and time elements, so it will filter based on the time too. If you want to use only the date part in the filter criteria, then you could use TRUNC. IT would truncate the time element.
I have answered a similar question, have a look at this https://stackoverflow.com/a/29005418/3989608
It looks like LOAD_STRT_DTM is a TIMESTAMP rather than a DATE, given the number of decimal points following the seconds. The only thing you have to be cautious about is that Oracle will convert a DATE to a TIMESTAMP implicitly where one of the operands is a TIMESTAMP. So the solution
WHERE load_strt_dtm > SYSDATE - 5
will work; as will
WHERE load_strt_dtm + 5 > SYSDATE
but the following will not:
WHERE SYSDATE - load_start_dtm < 5
the reason being that TIMESTAMP arithmetic produces an INTERVAL rather than a NUMBER.
first convert two dates to same format select datediff(dd,convert(varchar(20),'2015-01-01',112),convert(varchar(20),'01-10-2015',112))