Date in varchar and dd-mmm-yy format - sql

I am stuck in this query. The below part "TRANSMITTED_DATE LIKE '17-JUL-14'" is hardcoded. I want to make it a generalized one.
I want to do something like this
WHERE CAST(TRANSMITTED_DATE AS DATE FORMAT 'DD-MMM-YY') BETWEEN
CAST(CURRENT_DATE AS DATE FORMAT 'DD-MMM-YY')
AND CAST(CURRENT_DATE AS DATE FORMAT 'DD-MMM-YY')-7
i.e the last seven days record from the last time this query is run against the table.
But, the transmitted date is VARCHAR field in the table and format is like 31-OCT-13 i.e DD-MMM-YY.
Please help me with the query.
SELECT
MLI_MDL_NUMBER as DOCUMENTUM_MLI
,TRANSMITTAL_NUMBER
,PROJECT_ID
,TRANSMITTED_DATE
FROM GEEDW_PLP_BULK_V.CDR_DOCUMENTUM_TRSMTL
WHERE
( TRANSMITTED_DATE LIKE '17-JUL-14' OR
TRANSMITTED_DATE LIKE '18-JUL-14' OR
TRANSMITTED_DATE LIKE '19-JUL-14' OR
TRANSMITTED_DATE LIKE '20-JUL-14' OR
TRANSMITTED_DATE LIKE '21-JUL-14' OR
TRANSMITTED_DATE LIKE '22-JUL-14' OR
TRANSMITTED_DATE LIKE '23-JUL-14' OR
TRANSMITTED_DATE LIKE '24-JUL-14' OR
TRANSMITTED_DATE LIKE '25-JUL-14'
);

Depending on a global system setting (Century Break in dbscontrol) or your Teradata release this might be easy.
If you're on TD14 you can utilize Oracle's TO_DATE:
WHERE TO_DATE(TRANSMITTED_DATE, 'dd-mon-yy')
BETWEEN CURRENT_DATE - 7 AND CURRENT_DATE
Otherwise try following query and check what's returned:
SELECT CAST('17-JUL-14' AS DATE FORMAT 'DD-MMM-YY')
If it's 2014-07-17 you can simply use
WHERE CAST(TRANSMITTED_DATE AS DATE FORMAT 'DD-MMM-YY')
BETWEEN CURRENT_DATE - 7 AND CURRENT_DATE
If it's 1914-07-17
WHERE CAST(SUBSTRING(TRANSMITTED_DATE FROM 1 FOR 7) || '20' ||
SUBSTRING(TRANSMITTED_DATE FROM 8) AS DATE FORMAT 'DD-MMM-YY')
BETWEEN CURRENT_DATE - 7 AND CURRENT_DATE
Of course all go them are bad because every row needs to be converted from string to date, which is a big overhead and you'll loose an existing statistics.
If this is a big table and you need to run that query often you should try to change the datatype to a DATE and do the typecast once during import.
And there's another problem: if there's any string representing a non-valid date your query will fail.

Related

Format int as date in presto SQL

I have an integer date column "date_created" storing values like...
20180527, 20191205, 20200208
And am wondering what the best way to parse as a date is so I could do something like this in a query...
select * from table where formatted(date_created) > formatted(date_created) - 90
(to return everything within the last 90 days)
I've found some similar examples that convert from date ints representing seconds or milliseconds, but none where the columns are essentially date strings stored as integers.
Appreciate any thoughts on the best way to achieve this
And am wondering what the best way to parse as a date is so I could do something like this in a query...
You can convert "date as a number" (eg. 20180527 for May 27, 2018) using the following:
cast to varchar
parse_datetime with appropriate format
cast to date (since parse_datetime returns a timestamp)
Example:
presto> SELECT CAST(parse_datetime(CAST(20180527 AS varchar), 'yyyyMMdd') AS date);
_col0
------------
2018-05-27
However, this is not necessarily the best way to query your data. By adapting your search conditions to the format of your data (and not vice versa), you can potentially benefit from predicate push down and partition pruning. See #GordonLinoff answer for information how to do this.
You can do the comparison in the world of integers or of dates. You might as well convert the current date minus 90 days to a number:
select t.*
from t
where date_created >= cast(date_format(current_date - interval '90 day',
'%Y%m%d'
) as int
);
the below query is index friendly for any database since it does not use function on indexed column
select * from table where date_created > timestamp (formatted(date) - 90)
In addition, suppose we have date in format 20211011_1234 and we want one month older date and want back the original format, we can use the following formatting to convert date to int and vice versa.
select cast(date_format(
CAST(parse_datetime(cast(
split_part('20211011_1234', '_', 1) as varchar), 'yyyyMMdd')
AS date) - interval '30' day ,'%Y%m%d') as int) as column_name

Oracle query BETWEEN (date) AND (date)

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.

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))

Between operation for date in SQLite database

I have a table student with the following columns:
no - integer
name - string
startdate - date
enddate - date.
Date format is MM/DD/YYYY.
I will give a date as input. Now I need a query the inputdate which found in between the start and end date.
For an example I will give 04/14/2012, then the query should return the 1st record as in the figure.
(because input date (04/14/2012) is found in between the 04/10/2012 to 04/20/2012)
Please help me.
The issue you are having is caused by your assumption that sqlite has a date/datetime type when in fact it doesn't.
I suggest you read the following http://www.sqlite.org/datatype3.html to have a better understanding of sqlite types.
The dates in the MM/DD/YYYY format are handled as TEXT by sqlite, and so those dates are compared as strings. For example, 02/01/2012 is considered bigger than 01/02/2012by sqlite if compared directly.
You will need to transform those dates to a format that can be string-compared. Here is an example:
sqlite> create table foo (d TEXT);
sqlite> insert into foo values ('02/01/2012');
sqlite> select substr(d, 7, 4) || substr(d, 1, 2) || substr(d, 4, 2) from foo;
20120201
You should post what you have tried so far.
There should be a between clause that you can use:
select * from table
where inputdate between startdate and enddate
Dates as a date type in SQLite don't exist. There are a number of approaches to dealing with dates - store them as integer seconds since 1 Jan 1970 (unixepoch) or store them as strings, but if you do, then you really need to store them in 'YYYY-MM-DD' format because that is what the date functions require as input.
Assuming you use the string format in the format I suggested then your query would look something like
SELECT * FROM Table WHERE Date(Inputdate) BETWEEEN Date(startDate) AND Date(EndDate);
(although you may want to format the output of the date columns to US date format with
SELECT Strftime("%m/%d/%Y",startDate) As StartDate ...
If you use seconds since 1970 its somewhat easier because the seconds just compare without needing the convert them to dates, although you still might want to output in US date format, so ...
SELECT Strftime("%m/%d/%Y",startDate) As StartDate ... FROM Table WHERE inputDate BETWEEN startDate and EndDate;
sqlite> select *from tbl_node where mydate between '2014-02-02' and '2014-02-06';
it show the output :-
1|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:00:44
2|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:01:03
3|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:00:57
4|1|123|456|12eb-ab|1|1|254|123|19|2014-02-03 16:00:34
Here mydate is column name in tbl_node;
we can also use from current time , using now.
sqlite> select *from tbl_node where mydate between '2014-02-02' and 'now';

Filtering by date

I have a Date type column where are values in this format
1.1.2012 10:10:11
I need to create a filter which would filter these values by day, month and year.
I've tried
where like '% 1.1.2012 %'
but this seems to not working.
Oracle not store your date field formatted, but you can format the output with to_char function. For example:
select to_char(date_field,'dd/mm/yyyy hh24:mi:ss')
If you query a date without formatting, the output format will depend on the tool that you are using and your NLS_DATE parameter too.
To filter dates in Oracle you can use the to_date function, that receives an string and parse to date with some specific format. You can see all options of to_date here
Options to filter your date field:
where date_field between to_date('1.1.2012 00:00','d.m.yyyy hh24:mi') and to_date('1.1.2012 23:59','d.m.yyyy hh24:mi')
-- you possibly will lost some performance with this second one
where trunc(date_field) = to_date('1.1.2012','d.m.yyyy')
In MSSQL, you can use date-functions, that are easy to handle. One way would be like this:
where Year (date) = 2012
and Month(date) = 1
and Day (date) = 1
But there are other solutions. Take a look at the following page for mor information:
http://msdn.microsoft.com/en-us/library/ms186724.aspx
I worked recently with string-representations of datetime-values. I recommend not do it and to work always with the dates, because of compatibility, speaking of the MSSQL-Server.
If you use string-representations of datetime-values you need to be very careful with formats on different language-settings than the one on your own server.
Strings can be interpreted different on other servers (ISO-format vs us-format).
One possibility would be to do something like this:
WHERE date_and_time >=to_date( '01.01.2012','dd.mm.yyyy') and date_and_time <= to_date('01.01.2012','dd.mm.yyyy');
date_and_time is the name of your Date column.
edit: This is for Oracle