Obtain count to MI:SSSS precision? - oracle

TRANSACTION_DATE is a DATE data type.
This code lists all of the event dates to the MI:SSSS.
select to_char(transaction_date,'YYYY-MON-DD HH24:MI:SSSS') as trans_date from ticket_orders;
Now I want to get counts for those dates and I get ORA-00979 not a GROUP BY function.
select to_char(transaction_date,'YYYY-MON-DD HH24:MI:SSSS') as trans_date,
count(*)
from ticket_orders
group by to_char(transaction_date,'YYYY-MON-DD HH24:MI:SSSS');
ERROR ORA-00979: not a GROUP BY expression
How do I get a count of transactions to the MI:SSSS precision?

A DATE data type is a binary data type that is composed of 7 bytes representing century, year-of-century, month, day, hour, minute and second. It ALWAYS has those components and it NEVER contains fractional seconds (that is for the TIMESTAMP data type which can have fractional seconds and/or time zone information).
If DATE type does not store fractional seconds, why does a typical row from my first query look like this 2021-FEB-25 07:58:2626
That is because you are displaying the seconds twice as you use the SS format model for seconds twice.
Your query can just be:
select to_char(transaction_date,'YYYY-MON-DD HH24:MI:SS') as trans_date,
count(*)
from ticket_orders
group by
transaction_date;
db<>fiddle here

The DATE data type does not store fractional seconds. You can reference the Oracle documentation about data types.
DATE
Valid date range from January 1, 4712 BC, to December 31, 9999 AD. The
default format is determined explicitly by the NLS_DATE_FORMAT
parameter or implicitly by the NLS_TERRITORY parameter. The size is
fixed at 7 bytes. This data type contains the datetime fields YEAR,
MONTH, DAY, HOUR, MINUTE, and SECOND. It does not have fractional
seconds or a time zone.
If you want a data type that stores fractional seconds you will need to use TIMESTAMP
TIMESTAMP [(fractional_seconds_precision)]
Year, month, and day values of date, as well as hour, minute, and
second values of time, where fractional_seconds_precision is the
number of digits in the fractional part of the SECOND datetime field.
Accepted values of fractional_seconds_precision are 0 to 9. The
default is 6. The default format is determined explicitly by the
NLS_TIMESTAMP_FORMAT parameter or implicitly by the NLS_TERRITORY
parameter. The size is 7 or 11 bytes, depending on the precision. This
data type contains the datetime fields YEAR, MONTH, DAY, HOUR, MINUTE,
and SECOND. It contains fractional seconds but does not have a time
zone.

Related

Applying case when date

I have to set the start date as 01-01-year which would be pulled from the expense date field. I have written the below query
select to_date(extract(year from rpt.expense_date),'yyyy') from rpt
How can I set the date to 01-01-year which would be pulled from above query.
Thanks in advance.
Use TRUNC to truncate to the start of the year:
SELECT TRUNC(expense_date, 'YY') FROM rpt
You can just truncate the date value:
trunc(rpt.expense_date, 'YYYY')
By default the trunc() function truncates to midnight on the specified day, equivalent to trunc(<date>, 'DD'), but you can use other elements.
In your code:
to_date(extract(year from rpt.expense_date),'yyyy')
you are only supplying the year element to to_date(); in that situation the other date elements default to the first day of the current month - so today that would give you June 1st in that year, not January 1st. That's hidden away a bit in the documentation:
If you specify a date value without a time component, then the default time is midnight. If you specify a date value without a date, then the default date is the first day of the current month.

Convert Date strored as number(32,0) in oracle

I have an issue importing date from a Tririga database into a SQL database. Mainly I cant convert the date properly and it looks like is not the commont format I have seen around.
Eg date value incomming 775724400000
Running something like select to_date('765187200000', 'DDMMYYYYHH24MISS') my_date FROM dual;
give me an error
ORA-01847: day of month must be between 1 and last day of month
01847. 00000 - "day of month must be between 1 and last day of month"
I found the following info from this link seems to be also from tririga
link_help
And the size of the number are about 10 digits meanwhile this one is 12 and I know for fact this dates should be from the past 10 years (most of them)
I can't seem to find anything that gives me an answer how to convert this into proper dates.
Any suggestions?
The input number appears to be "epoch", a count of milliseconds elapsed since 1 January 1970 GMT (UTC).
To convert to date is not difficult:
select date '1970-01-01' + (775724400000 / 86400000) as dt from dual;
DT
--------------------
1994-Aug-01 07:00:00
Note the hard-coded literals: date '1970-01-01' (epoch is by definition measured from midnight on this date) and 86400000. By one of the definitions (in the previous version of the International System of Units and Weights), a second is 1/86400 of a median day. In Oracle, date arithmetic is based on the number 1 representing one day, so to convert your milliseconds to days you must divide your input by 86400 * 1000.
The most delicate question has to do with time zones (and possibly daylight saving time, also related to time zone). In most cases, epoch is measured from midnight on 1 January 1970 GMT, not from midnight on 1 January 1970 in local time. Do you need to adjust for that? Only you and your business users can answer that question.
(As an aside, the number you provided does NOT represent a date in the past 10 years - not even close.)

Convert difference of dates to date with timestamp

How to convert the difference of 2 dates with a timestamp to date with timestamp again, Oracle giving number but i want to compare timestamp.
select emp_date>to_date(sysdate,'yyyy-MM-dd HH24:MI:SS')-todate('2021-03-22 10:20:12') from emp;
above query giving error: expected date but got NUMBER.
Thanks in advance
What you are saying makes no sense. Difference of two DATE datatype values is number of days between them. For example
SQL> select sysdate - to_date('21.03.2021 13:12', 'dd.mm.yyyy hh24:mi') diff from dual;
DIFF
----------
,943217593
SQL>
You CAN convert it to a prettier format (days, hours, minutes, seconds), but it is still a NUMBER, it is not a date.
Therefore, you can't compare EMP_DATE (which is a DATE datatype column, isn't it?) to a number as it just doesn't make sense.
Is 22nd of March 2021 larger or smaller than 0.94? It's neither.
[TL;DR] You cannot as your data types do not match and it does not make sense to compare a date/time value to an interval.
If you do:
date_value1 - date_value2
You will get a NUMBER data type representing the number of (fractional) days between the two date values.
You can explicitly cast the subtraction operation to get an INTERVAL DAY TO SECOND data type using:
(date_value1 - date_value2) DAY TO SECOND
So, for your code that would be:
SELECT emp_date > ( sysdate - TO_DATE( '2021-03-22 10:20:12', 'YYYY-MM-DD HH24:MI:SS' ) ) DAY TO SECOND
FROM emp;
However, that will fail as you cannot compare a DATE to an INTERVAL DAY TO SECOND and SQL does not have a boolean data type so > does not make sense.
To fix that later point you could use a CASE expression but the difference in data types is a show-stopper as you can't compare a date to an interval.
but i want to compare timestamp.
You don't have a TIMESTAMP data type, you have either a number (representing an interval in days) or an INTERVAL data type. If you want to convert it back to a DATE or TIMESTAMP then you need to add your interval to an epoch value.

Converting XML date (ISO-8601) into timestamp in Oracle

Could you please help me in converting date time of format from "2015-02-23T16:26:41.485+05:30" to "23-FEB-15 16.26.41.000000000 AM" in Oracle.
I have an ISO-8601 date string in variable:
START_TIME='2015-02-23T16:26:41.485+05:30'
When I use
to_timestamp(START_TIME,'yyyy-mm-dd"T"hh24:mi:ss.ff3')
I get:
Error report:
ORA-01830: date format picture ends before converting entire input string
ORA-06512: at line 55
01830. 00000 - "date format picture ends before converting entire input string"
*Cause:
*Action:
To convert your string to a timestamp with time zone value, you need the to_timestamp_tz() function:
select to_timestamp_tz('2015-02-23T16:26:41.485+05:30',
'yyyy-mm-dd"T"hh24:mi:ss.ff3tzh:tzm') as result
from dual;
RESULT
-----------------------------------
2015-02-23 16:26:41.485000 +05:30
This includes the TZH and TZM datetime format model elements to handle the time zone offset; those can't be used in to_timestamp() or to_date() as those data types don't understand time zones.
You seem to want to lose the fractional seconds part, and the time zone information; you can achieve both at once by casting to a timestamp (without timezone) with the fractional seconds precision set to zero:
select cast(to_timestamp_tz('2015-02-23T16:26:41.485+05:30',
'yyyy-mm-dd"T"hh24:mi:ss.ff3tzh:tzm') as timestamp(0)) as result
from dual;
RESULT
-----------------------------------
2015-02-23 16:26:41.000000
But losing the time zone seems dangerous, unless you are sure that the data you receive is always going to be in the same time zone as your database. If you might have different time zones in the data but for some reason don't want to retain that information, you can also convert to a specific time zone for storage, but it isn't clear whether you need or want that here. If you aren't keeping the time zone or the fractional seconds, you may be better off with a date anyway.
Dates and timestamps do not have any inherent format within the database. If you then want to see that converted back into a string in the format you specified, pass it back into a to_char() call with the formatting you want; but as your example has both a 24-hour-clock hour value and an (incorrect) AM/PM indicator that isn't clear either. Maybe you want:
select to_char(cast(to_timestamp_tz('2015-02-23T16:26:41.485+05:30',
'yyyy-mm-dd"T"hh24:mi:ss.ff3tzh:tzm') as timestamp(0)),
'dd-MON-rr hh:mi:ss.ff9 am') as result
from dual;
RESULT
-----------------------------------
23-FEB-15 04:26:41.000000000 PM
To store the value from your START_TIME variable in a timestamp column the approach is exactly the same, just use that instead of the fixed value I've used above to demonstrate the conversion:
cast(to_timestamp_tz(START_TIME, 'yyyy-mm-dd"T"hh24:mi:ss.ff3tzh:tzm')
as timestamp(0))

Convert time stored as hh24miss to hh24:mi:ss

I have a column in my table which will store the time as hh24miss format, i.e it stores as 091315 which is 09 hrs 13 min 15 sec. I need to convert it into HH24:MI:SS AND concatenate it with the date column which is in YYYYMMDD format.
Simply, the following columns Date: 19940601 and Time: 091315 need to be converted to
01-Jan-94 09:13:15.
You should not store dates as strings, and there is no need to store the time in a separate field. Oracle's DATE data type includes times down the to the second. (You'd need TIMESTAMP for fractions of a second).
If you are really stuck with this schema then you need to convert the two strings into a DATE:
to_date(date_column || time_column, 'YYYYMMDDHH24MISS')
You can then display that in whatever format you want; what you showed would be:
to_char(to_date(date_column || time_column, 'YYYYMMDDHH24MISS'),
'DD-Mon-RR HH24:MI:SS')
Although the data you have is June, not January.
SQL Fiddle demo.
But really, please revisit your schema and use the appropriate data type for this, don't store the values as strings. You have no validation and no easy way to check that the values you have stored actually represent valid dates and times.

Resources