How to change this expression to date in ORACLE - oracle12c

How can I change below expression to give me a output in format MMM d, yyyy given the below act_start_date_time is a date column in ORACLE.
select DECODE(MAX(A.NAME), NULL, NULL, max(act_start_date_time))

If act_start_date_time is a column of datatype date then you should not be passing it into the to_date() function. If you do:
to_date(act_start_date_time, 'YYYY/MON/DD HH:MI:SS')
then you are implicitly converting the date to a string using your session's NLS settings, so it's really:
to_date(to_char(act_start_date_time), 'YYYY/MON/DD HH:MI:SS')
which is
to_date(to_char(act_start_date_time, <NLS_DATE_FORMAT>), 'YYYY/MON/DD HH:MI:SS')
which will either error, give you the same date back, or give you a different date, depending on what your current NLS_DATE_FORMAT is and the original value you're looking at. For instance:
alter session set nls_date_format = 'DD-MON-RR';
select to_date(sysdate, 'YYYY/MON/DD HH:MI:SS') from dual;
TO_DATE(S
---------
17-AUG-02
so 2017-08-02 has been translated to [20]02-08-17. Which is not helpful.
To convert a date into a formatted string you need to use the to_char() function instead, e.g. something like:
decode(max(a.name),null,null, to_char(max(rca.act_start_date_time), 'YYYY/MON/DD HH:MI:SS'))
or
to_char(case when max(a.name) is not null then max(rca.act_start_date_time) end, 'YYYY/MON/DD HH:MI:SS')
or to get the format you first asked about use format mask 'FMMon DD, YYYY'. The FM modifier removes leading zeros from the day number. But with all of those, be aware that NLS settings still have an effect; the abbreviated month name will be shown in the session's date language; if you need to make sure it's always shown in a specific language you can supply that as the optional third argument to the function:
select to_char(sysdate, 'FMMon DD, YYYY', 'NLS_DATE_LANGUAGE=ENGLISH') from dual;
TO_CHAR(SYSDATE,'FMMO
---------------------
Aug 2, 2017
select to_char(sysdate, 'FMMon DD, YYYY', 'NLS_DATE_LANGUAGE=FRENCH') from dual;
TO_CHAR(SYSDATE,'FMMONDD,YYYY
-----------------------------
Août 2, 2017
Quick demo with fake data from CTEs and relying on the session language:
with a (id, name) as (select 1, null from dual union all select 2, 'Joe' from dual),
rca (id, act_start_date_time) as (select 1, sysdate from dual union all select 2, sysdate from dual)
select a.id,
max(a.name),
decode(max(a.name), null, null,
to_char(max(rca.act_start_date_time), 'YYYY/MON/DD HH:MI:SS')) as string1,
to_char(case when max(a.name) is not null then max(rca.act_start_date_time) end,
'YYYY/MON/DD HH:MI:SS') as string2,
to_char(case when max(a.name) is not null then max(rca.act_start_date_time) end,
'FMMon DD, YYYY') as string3
from a
join rca on rca.id = a.id
group by a.id;
ID MAX STRING1 STRING2 STRING3
---------- --- -------------------- -------------------- ---------------------
1
2 Joe 2017/AUG/02 11:03:47 2017/AUG/02 11:03:47 Aug 2, 2017
(Without your table structures or sample data I can't comment on whether the aggregation and conversion is appropriate, so adapt as needed for your real scenario...)
The date format models are listed in the documentation.

Related

How to pass datetime field in UTC format as a parmeter in Query in DB2

I have a date time field which is coming from an external system in UTC format 2022-01-02T08:00:00.000+00:00. This value should be queried in DB2 to determine whether the record exists or not. The date stored in DB2 is in the format 2022-01-01 08:00:00.000 Is there any way to convert the incoming date in the format 2022-01-01 08:00:00.000 ?
The final query should be something like
select * from table where changedate = '2022-01-02T08:00:00.000+00:00'
Db2 doesn't store timestamps in a string format. Some binary format is used for that.
So, if I got you right, your question should be changed to "how to convert YYYY-MM-DDTHH24.MI.SS.FF3XXXXXX string representation of timestamp to the timestamp data type".
Unfortunately, there is no such a built-in pattern in the TO_DATE / TIMESTAMP_FORMAT function, but you can use the following expression. T column has the timestamp data type, and you may use this expression in the select * from table where changedate = ... statement.
SELECT
S
, TO_DATE (TRANSLATE (SUBSTR (S, 1, 23), ' ', 'T'), 'YYYY-MM-DD HH24:MI:SS.FF3')
+ CAST (TRANSLATE (SUBSTR (S, 24), '', ':', '') || '00' AS DEC (6)) AS T
FROM
(
VALUES
'2022-01-02T08:00:00.000+00:00'
, '2022-01-02T08:00:00.000+03:30'
, '2022-01-02T08:00:00.000-03:30'
) T (S)
S
T
2022-01-02T08:00:00.000+00:00
2022-01-02-08.00.00.000000
2022-01-02T08:00:00.000+03:30
2022-01-02-11.30.00.000000
2022-01-02T08:00:00.000-03:30
2022-01-02-04.30.00.000000

Converting GMT to CST in postgresql

I am currently working with raw data that have timestamps in GMT and I want to convert them to CST. I am trying to use the cast function to change the timestamp, but it is not working- the times are not affected. Most of what I have read about timezones in postgresql assumes that the default timezone is UTC so I'm not sure if there is a different syntax needed for when the data I'm trying to convert is GMT. Any help is greatly appreciated!
WITH RECURSIVE "child" AS (
SELECT "ConsultantDisplayID",
"JoinDate",
"ParentPersonDisplayID"
FROM "public"."flight_export_consultant"
WHERE "ConsultantDisplayID" = '4019'
UNION
SELECT c."ConsultantDisplayID",
CAST(c."JoinDate" at time zone 'america/chicago' as timestamp) as "JoinDate"
c."ParentPersonDisplayID"
FROM "public"."flight_export_consultant" AS c
JOIN "child" AS cd
ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
"sponsor" AS (
SELECT
"child".*,
c1."ConsultantDisplayID",
Cast(c."JoinDate" at time zone 'america/chicago' as timestamp) as "Sponsor JoinDate"
FROM "public"."flight_export_consultant" AS c1
LEFT JOIN "child"
ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")
SELECT * FROM "sponsor"
As #Mike Organek pointed out a field of type timestamp assumes local time on entry. So first thing you need to establish is where the dates are being entered from and whether they are are actually being entered as GMT. For the moment assuming they are you could do the following:
select 'September 24, 2018, 4:01PM'::timestamp at time zone 'utc' at time zone 'america/chicago';
timezone
---------------------
09/24/2018 11:01:00
-- Or if you want to stick to GMT
select 'September 24, 2018, 4:01PM'::timestamp at time zone 'gmt' at time zone 'america/chicago';
timezone
---------------------
09/24/2018 11:01:00
Basically you are 'anchoring' the timestamp at UTC/GMT and then converting to 'america/chicago'. In other words replicating what a timestamptz field does.
Given that JoinDate is type timestamp, this should be a good workaround for your situation now that we have established that the values in JoinDate of type timestamp represent UTC/GMT timestamps, and your server is not in UTC/GMT. The ideal solution is to use timestamptz columns.
The trick here is to cast JoinDate to text, append a z to it to make it UTC, and then cast it to timestamptz. Once that is done, you can use at time zone 'us/chicago' to do the conversion for you.
WITH RECURSIVE "child" AS (
SELECT "ConsultantDisplayID",
"JoinDate",
"ParentPersonDisplayID"
FROM "public"."flight_export_consultant"
WHERE "ConsultantDisplayID" = '4019'
UNION
SELECT c."ConsultantDisplayID",
"JoinDate",
c."ParentPersonDisplayID"
FROM "public"."flight_export_consultant" AS c
JOIN "child" AS cd
ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
"sponsor" AS (
SELECT
"child".*,
c1."ConsultantDisplayID",
c."JoinDate" as "Sponsor JoinDate"
FROM "public"."flight_export_consultant" AS c1
LEFT JOIN "child"
ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")
SELECT "ConsultantDisplayID",
("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "JoinDate",
"ParentPersonDisplayID",
"ConsultantDisplayID",
("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "Sponsor JoinDate"
FROM "sponsor";

Converting Integer values to Date in Presto SQL

Below is a script i am trying to run in Presto; Subtracting today's date from an integer field I am attempting to convert to date. To get the exacts days between. Unfortunately, it seems the highlighted block does not always convert the date correctly and my final answer is not correct. Please does anyone know another way around this or a standard method on presto of converting integer values to date.
Interger value in the column is in the format '20191123' for year-month-date
select ms, activ_dt, current_date, date_diff('day',act_dt,current_date) from
(
select ms,activ_dt, **CAST(parse_datetime(CAST(activ_dt AS varchar), 'YYYYMMDD') AS date) as act_dt**, nov19
from h.A_Subs_1 where msisdn_key=23480320012
) limit 19
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
You can use below sample query for your requirement:
select date_diff('day', date_parse('20191209', '%Y%m%d'), current_timestamp);

SSRS/TSQL date formatting

Using the following sample query below in SSRS would return month as single number(1-12). What I want to is to display the date as is something like Jan 2000. How would I go about changing my code to be able to format from single number month to a MMM YYYY format? I tried the formatting in visual studio itself but it is currently returning as MMM YYYY.
select distinct count(*) as Count,
con.STATE,
month(con.sub_Date) as Month,
year(con.sub_Date) as Year
from contract con
group by con.STATE,month(con.sub_date),year(con.sub_date)
I strongly recommend that you perform the formatting of the date at the report level.
Return the date from your query as the first date of the desired period, but then set the format string for the placeholder/text box.
The reason to do this is so that sorting and data manipulation works as expected when the report is exported to Excel.
So I would use a query as:
SELECT DISTINCT
COUNT(*) AS Count ,
con.STATE ,
DATEADD(MONTH, DATEDIFF(MONTH, 0, con.sub_Date), 0) AS FirstOfMonth
FROM
contract con
GROUP BY
con.STATE ,
DATEADD(MONTH, DATEDIFF(MONTH, 0, con.sub_Date), 0)
and then use formatting codes in the report such as MMM, YYYY for display and break the date apart with =Month(fields!FirstOfMonth.Value) if you need the components for grouping. This will allow the users to pivot the data appropriately if needed.
Formatting of the dates is presentation logic, and should be kept out of SQL if possible.
You could add the following into the query to return the pre-formatted month/year as part of the report dataset - maybe easier than trying to reconstruct it at the report level:
select distinct count(*) as Count,
con.STATE,
month(con.sub_Date) as Month,
year(con.sub_Date) as Year,
left(datename(mm, sub_Date), 3) + ' ' + cast(year(sub_Date) as char(4)) as MonthYear
from contract con
group by con.STATE,
month(con.sub_date),
year(con.sub_date),
left(datename(mm, sub_Date), 3) + ' ' + cast(year(sub_Date) as char(4))
I usually prefer to use CONVERT to get partial dates, though I don't see any CONVERT date formats that would leave you cleanly with a MON YYYY output. However, format 106 will get you most of the way there. So combining that with RIGHT() will get you the date in the format you're looking for.
SELECT DISTINCT
COUNT(*) AS Count ,
[con].[STATE] ,
MONTH([con].[sub_Date]) AS Month ,
YEAR([con].[sub_Date]) AS Year ,
RIGHT(CONVERT(CHAR(11), [con].[sub_Date], 106), 8) AS MonthYear
FROM [dbo].[contract] AS con
GROUP BY [con].[STATE] ,
MONTH([con].[sub_Date]) ,
YEAR([con].[sub_Date]) ,
RIGHT(CONVERT(CHAR(11), [con].[sub_Date], 106), 8)

Oracle:Update date column in a table

Following is my oracle update query that`s throwing error--
Update table Set col1 = To_date(:dateFill, 'mm/dd/yyyy hh24:mi:ss') Where Fil1 = :ID;
dateFill = 01/05/2012,
ID= 15
this statement is executing in a procedure,
error -:ORA-01722: invalid number(date field)
Can someone tell me why is 'select To_date('01/05/2012 00:00:00', 'mm/dd/yyyy hh24:mi:ss') from dual;' giving me result like '05-JAN-2012 00:00:00'.???
Please suggest me some answers.
If dateFill = 01/05/2012, why are you specifying a date format that includes "hh24:mi:ss"?
An ORA-01722 error occurs when an attempt is made to convert a character string into a number, and the string cannot be converted into a valid number. Valid numbers contain the digits '0' through '9', with possibly one decimal point, a sign (+ or -) at the beginning or end of the string, or an 'E' or 'e' (if it is a floating point number in scientific notation).
to_date always work with 'character' ie
to_date(char[,'format'[,nls_lang])
Your variable 'dateFill' is of Number datatype. Cast or convert this 'dateFill'
field into varchar and things will work.
Can someone tell me why is 'select To_date('01/05/2012 00:00:00',
'mm/dd/yyyy hh24:mi:ss') from dual;' giving me result like
'05-JAN-2012 00:00:00'.???
how a date displays is down to your client / Nls date format setting:
SQL> select To_date('01/05/2012 00:00:00','mm/dd/yyyy hh24:mi:ss') from dual;
TO_DATE('01/05/20120
--------------------
05-jan-2012 00:00:00
SQL> alter session set nls_date_format='mm/dd/yyyy hh24:mi:ss';
Session altered.
SQL> select To_date('01/05/2012 00:00:00','mm/dd/yyyy hh24:mi:ss') from dual;
TO_DATE('01/05/2012
-------------------
01/05/2012 00:00:00
SQL>