Date_Trunc and To_Date Questions SQL - sql

Can we use date_trunc for a date (not date-time) that we are trying to "truncate" (not sure if the term can be applied here) to e.g. the start of the week? So if I have date_trunc(week, 28/10/2020) and I want to get the start of the week that 28th of October lies in (so 26th of October)? I tried this in my SQL command line but I get error messages.
If I am doing: SELECT to_date ('02 Oct 2001', 'DD Mon YYYY'); How can I ensure the resulting format is in a date format I specify (rather than the default date format)? For example if I want it in format DD-MM-YYYY?
select to_char(date '2017-06-02', 'MM') < in this example, why do we need "date" for this to work? The general format for to_char should be TO_CHAR (timestamp_expression, 'format'). I don't see in this general format that we need "day".
if I have a WHERE filter like to_char(order_date, '20-10-2020'), and there are indeed some rows with this order date, will these rows still show in my results (after running query) if these rows are in DATE format (so 20 Oct is in date format) as opposed to string (which is what I am filtering by as I am doing to_char). I know there would be no need to use to_char in this case but just asking..

yes, you can use date in text form but you have to cast it to a correct type
these queries will work
select date_trunc('week', '2020-10-28'::date);
select date_trunc('week', '10/28/2020'::date);
-- as well as
select date_trunc('week', '2020-10-28'::datetime);
and return timestamp 2020-10-26 00:00:00.000000
note, next query
select date_trunc('week', '28/10/2020'::date);
will fail with error date/time field value out of range: "28/10/2020";
You can use to_char, it returns text, if you need a date format you have to case it again
select to_char( to_date ('02 Oct 2001', 'DD Mon YYYY'), 'DD-MM-YYYY')::date;
select to_char('02 Oct 2001'::date, 'DD-MM-YYYY')::date;
'2017-06-02' is a text and it can't be automatically converted to timestamp. Actually I don't know a text format which can.
No, you need to explicitly cast into date type to use it as a filter
where order_date = date_stored_as_a_text::date

I am answering the questions in a different order as there are some wrong assumptions:
Question 3
There is a general difference between '2017-06-02' and date '2017-06-02' - the first one is just a varchar, a string, NOT handled as a date by Redshift, the 2nd one tells Redshift to handle the string as date and therefore works.
Question 2
A date data type column has no format - you may an sql client that can display date columns in different formats, however, this is not a functionality of redshift. SELECT to_date ('02 Oct 2001', 'DD Mon YYYY'); tells redshift to convert the string '02 Oct 2001' to date.
Question 1
DATE_TRUNC('datepart', timestamp) also supports week as datepart - see Date parts for date or timestamp function (Also shown in the example of AWS). You should also be able to provide a date instead of a timestamp.
Question 4
to_char(order_date, '20-10-2020')is not a filter and you are using it wrong.
AWS TO_CHAR
TO_CHAR converts a timestamp or numeric expression to a character-string data format.
I guess you are rather looking for:
where to_char(order_date, 'YYYY-MM-DD') = '20-10-2020'

Related

How to fetch month from date where date column is in varchar datatype. FYI using snowflake tool

How to fetch month from date where date column is in varchar datatype. FYI using snowflake tool.
For example if i want data of june month ? how can i fetch ?
You can use the TO_DATE(…) function to treat the VARCHAR column as a formatted date type, and the EXTRACT(…) function to retrieve just the month out of the date.
If your date string is formatted in a well-known manner, TO_DATE's automatic parsing (or a direct cast using the :: operator) will suffice, and you can write your query this way:
SELECT * FROM table
WHERE
EXTRACT(month, TO_DATE(varcharCol)) = 6 -- June of every year
AND EXTRACT(year, varcharCol::DATE) = 2020; -- June of 2020 alone
Alternatively, if the date is in a non-standard format, use available formatting options to make TO_DATE(…) parse it properly:
-- Dates of custom format, such as: 'June # 02 # 2020'
SELECT
EXTRACT(month, TO_DATE(varcharCol, 'MMMM # DD # YYYY')) AS month
FROM table
WHERE
month = 6;
Note: You can also swap all DATE and TO_DATE above with TIMESTAMP and TO_TIMESTAMP if the data carries a whole timestamp value within it instead of only a date.
First of all, you shouldn't store dates as strings. But you probably know that.
If you do store dates as strings, you store them all in one particular format, say, 'mm/dd/yyyy'. So, use a substring function to get the month digits.
For 'mm/dd/yyyy':
where substring(date_string, 1, 2) = '06'
For 'yyyy-mm-dd':
where substring(date_string, 9, 2) = '06'
In many situations you can also use LIKE:
For 'mm/dd/yyyy':
where date_string like '06%'
For 'yyyy-mm-dd':
where date_string like '%-06-%'
You have to use to_date in snowflake to convert varchar datatype to date as following
select *
from yourTable
where to_date(yourDateColumn, 'YYYY-MM-DD') >= '2020-06-01'
and to_date(yourDateColumn, 'YYYY-MM-DD') <= '2020-06-30'

Extract Month, Year (Netezza SQL)

My data type is a date formatted as "YYYY-MON-DD" and I would like to extract the month and year to be formatted as "MON YYYY" while keeping the data type as date so that I will be able to use it with the ADD_MONTHS function. Is there a way to do so? I extract the date from the data field called date_process.
This is what I thought of but it doesnt seem to be working.
SELECT TO_DATE(TO_CHAR(PROCESS_DATE,'YYYY-MON'), 'MON YYYY') AS PERIOD,
Thank you.
Dates are stored in an internal format, not as a string.
If you want to see the value in a particular format, then you need to convert it to a string. Hence, drop the final to_date():
SELECT TO_CHAR(PROCESS_DATE, 'MON YYYY') AS PERIOD,

String to date conversion in query

i have the following "timestamp" in the column
Mon Aug 10 12:24:46 CDT 2016
so to convert into date, i am doing the following.
select * from
(select TO_DATE(SUBSTR(t.timestamp,9,2) || '-' || SUBSTR(t.timestamp,5,3) ||
'-' || SUBSTR(t.timestamp,27,2), 'DD-MON-YY') from table t where
t.LENGTH(TRIM(t.timestamp)) = 28 as date) where date <= sysdate;
The reason for doing that is, "Oracle sysdate" is returning a current date in the following format
20-SEP-16
So to compare the oracle sysdate, i am using the above approach.
is there any better approach for doing this, i knew this is inefficient using a group of sub-strings inside a select statement and since my "time stamp" value is too long, i am unable to convert to ORACLE date.
I am using oracle 11 as my Database. any help is appreciated.
Here is a proof of concept, assuming the so-called "timestamp" is in fact a string. If it is a proper timestamp with time zone (as it should be), then it's even simpler, you can compare to a date directly.
Note two things: In my mapping I don't have "CDT" for some reason but I do have the standard time zone, CST. I am probably missing a daylight savings time file which I don't care to hunt down and install. And Aug-10-2016 was a Wednesday; Monday won't work, you can't fool Oracle. Wonder why you didn't bother to use an actual, correct date (including the correct day of the week).
Edit: Actually I am not missing any "time zone codes file"; instead, to recognize CDT as a valid time zone, the TZR component in the model below needs to be changed to TZD.
PROOF OF CONCEPT:
select 'x' as col1
from dual
where to_timestamp_tz('Wed Aug 10 12:24:46 CST 2016',
'Dy Mon dd hh24:mi:ss TZR yyyy') <= sysdate
;
COL1
-----
x
1 row selected.
The as date is in the wrong place.
'Aug' is a month name abbreviation in a certain language. Specify that language in to_char to make sure it works independent of your current setting.
Don't only use YY when you have YYYY available.
At last there is the time zone 'CDT'. Is it always 'CDT' or can it be something else? If you need to get from one time zone to another, you'd have to convert to timestamp with timezone first, then move to the other timezone, then convert to date.
Here is the query:
select *
from
(
select
cast(from_tz(cast("date" as timestamp), zone) at time zone 'CDT' as date) as "date"
from
(
select to_date(substr(t.timestamp,9,2) || '-' ||
substr(t.timestamp,5,3) || '-' ||
substr(t.timestamp,25,4),
'DD-MON-YY',
'NLS_DATE_LANGUAGE=AMERICAN') as "date",
substr(t.timestamp,21,3) as zone
from table t
where t.length(trim(t.timestamp)) = 28
)
)
where "date" <= sysdate;
Despite its name from_tz doesn't convert from a timezone, but from a timestamp without timezone to a timestamp with timezone. So we use this to put our timezone information in. timestamp at time zone 'xyz' on the other hand moves the timezone to the one specified (the one we interprete our dates to reside in). cast is used to get from date to timestamp and vice versa.
You can use TO_CHAR function to extract date formate
https://docs.oracle.com/database/121/SQLRF/functions216.htm

Formatting value of year from SYSDATE

I want to insert the current date into one of the columns of my table. I am using the following:
to_date(SYSDATE, 'yyyy-mm-dd'));
This is working great, but it is displaying the year as '0014'. Is there some way that I can get the year to display as '2014'?
Inserting it as TRUNC(sysdate) would do. Date actually doesn't have a format internally as it is DataType itself. TRUNC() actualy will just trim the time element in the current date time and return today's date with time as 00:00:00
To explain what happened in your case.
say ur NLS_DATE_FORMAT="YY-MM-DD"
The Processing will be like below
select to_date(to_char(sysdate,'YY-MM-DD'),'YYYY-MM-DD') from dual;
Output:
TO_DATE(TO_CHAR(SYSDATE,'YY-MM-DD'),'YYYY-MM-DD')
January, 22 0014 00:00:00+0000
2014 - gets reduced to '14' in first to_char() and later while converted again as YYYY.. it wil be treated as 0014 as the current century detail is last!
to_date is used to convert a string to a date ... try to_char(SYSDATE, 'yyyy-mm-dd') to convert a date to a string.
The to_date function converts a string to a date. SYSDATE is already a date, so what this will do is to first convert SYSDATE to a string, using the session's date format as specified by NLS settings, and then convert that string back to date, using your specified date format (yyyy-mm-dd). That may or may not give correct results, depending on the session's NLS date settings.
The simple and correct solution is to skip the to_date from this and use SYSDATE directly.
Try this to_date(SYSDATE, 'dd-mm-yy')

issue with add_month date using PostgreSQL

I am trying to use the add_month function but getting an error. I want to get the number of visits between [CAL_DATE - 13 months] and [CAL_DATE]. The format of the dates are as following: 2007-14, 2010-05, 2009-04 and etc. this is the error I am getting
"Bad time stamp external representation '2009-11"
and here is the code I am using. I can't seem to figure out the issue.
CAL_DATE BETWEEN add_months(CAL_DATE,-13) AND CAL_DATE.
I am using netezza database.
Presumably add_months expects a date as its first argument and returns a date. You don't have dates, you have YYYY-MM strings so you have two problems:
add_months won't know what to do with a YYYY-MM string.
BETWEEN won't know what to do with a date and a YYYY-MM string.
If you want to use add_months then you'll have to give it a date and convert the date it gives you to one of your YYYY-MM strings with something like this:
to_char(add_months((cal_date || '-01')::date, -13), 'yyyy-mm')
Appending -01 to your strings should give you a string representation of the first of that month and you should be able to cast that to a date with ::date. Then a to_char to convert the result of add_months back to your YYYY-MM format.
Alternatively, since add_months isn't really doing anything useful for you here, just use a PostgreSQL interval for the month adjustment:
to_char((cal_date || '-01')::date - interval '13 months', 'yyyy-mm')