I've got this query:
SELECT user_id, from_loc_id, to_loc_id, to_char(dstamp, 'hh24:mi:ss')
FROM inventory_transaction
WHERE code = 'Pick'
AND substr(work_group,1,6) = 'BRANCH'
AND dstamp BETWEEN to_date('24/02/2022 17:00:00', 'dd/mm/yyyy hh24:mi:ss') AND
to_date('24/02/2022 18:00:00', 'dd/mm/yyyy hh24:mi:ss')
ORDER BY user_id;
That's the output:
My expected output is:
I was trying to use lag, but didn't really worked.
I've just realized I need to add a second ORDER BY, so first by user, second by to_char(dstamp, 'hh24:mi:ss').
All solutions much appreciate. Thank you.
You can use NUMTODSINTERVAL function with day argument and applying SUBSTR to extract hours:minutes:seconds portion as your data resides within a specific date such as
SELECT t.user_id,
t.dstamp,
SUBSTR(
NUMTODSINTERVAL(dstamp - LAG(dstamp)
OVER (PARTITION BY user_id ORDER BY dstamp),'day'),
12,8) AS time_diff
FROM t
Demo
Edit : The case above is applied for the column dstamp is considered to be of date data type, if its data type is timestamp, then use the following query containing date cast instead
SELECT t.user_id,
t.dstamp,
SUBSTR(
NUMTODSINTERVAL(CAST(dstamp AS date) - LAG(CAST(dstamp AS date))
OVER (PARTITION BY user_id ORDER BY CAST(dstamp AS date)),'day'),
12,8) AS time_diff
FROM t
Demo
Related
I am trying to get transaction counts for every hour. Normally it is a straight forward query by unfortunately the timestamp column I have to work with is not timestamp but varchar2! No matter what I try I get either "not a valid month" or "invalid number", depending on the format I use.
The timestamp looks like: 2021-08-08 00:00:52:632
I also executed the following to get NLS format:
SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';
and get
DD-MON-RRRR.
This is the latest I tried among a dozen others (I commented out the "group by" to just get the darn thing to display).
select to_char(reqts,'mm/dd/yyyy hh24') DATE_HR
--, count(*)
from idcreqresplog
where logdate > trunc(SYSDATE -2)
and logtypeid in (2,4)
--group by to_char(reqts,'mm/dd/yyyy hh24');
Also
select to_char(reqts, 'yyyy-mm-dd hh24:mi:ss.fff' )
--, count(*)
FROM
reqresplog
WHERE
logdate > trunc(SYSDATE -2) ;
--group by to_date(reqts, 'yyyy-mm-dd HH4');
At my wits end and need some help.
Assuming that your column is always in the format 2021-08-08 00:00:52:63 then group on the substring up to the 13th character:
SELECT SUBSTR(reqts, 1, 13) AS date_hr,
count(*)
FROM idcreqresplog
WHERE logdate > trunc(SYSDATE -2)
AND logtypeid in (2,4)
GROUP BY
SUBSTR(reqts, 1, 13);
If you do want to convert to a date then, from Oracle 12.2, you can use TO_TIMESTAMP(string_value DEFAULT NULL ON CONVERSION ERROR, 'YYYY-MM-DD HH24:MI:SS:FF'):
SELECT TRUNC(
TO_TIMESTAMP(
reqts DEFAULT NULL ON CONVERSION ERROR,
'YYYY-MM-DD HH24:MI:SS:FF'
),
'HH'
) AS date_hr,
COUNT(*)
FROM idcreqresplog
WHERE logdate > trunc(SYSDATE -2)
AND logtypeid in (2,4)
GROUP BY
TRUNC(
TO_TIMESTAMP(
reqts DEFAULT NULL ON CONVERSION ERROR,
'YYYY-MM-DD HH24:MI:SS:FF'
),
'HH'
)
db<>fiddle here
Assuming as LittleFoot suggested, that some of your data is bad, you can use an inline WITH function to root out your bad data. Take the following example:
WITH FUNCTION get_timestamp
(
p_sTimeString VARCHAR2
)
RETURN TIMESTAMP
IS
BEGIN
RETURN TO_TIMESTAMP(p_sTimeString, 'YYYY-MM-DD HH24:MI:SS.FF3');
EXCEPTION WHEN OTHERS THEN RETURN NULL;
END;
SELECT TO_CHAR(s.hour, 'YYYY-MM-DD HH24') AS HOUR, COUNT(*) AS ROW_COUNT
FROM (SELECT TRUNC(get_timestamp(td.time), 'HH24') AS HOUR,
td.amount
FROM test_data td) s
WHERE s.hour IS NOT NULL
GROUP BY s.hour
ORDER BY s.hour;
Here is the DBFiddle showing this working for some good and bad data (Link).
What the query does is use an inline function to call the TO_TIMESTAMP function. Then it just catches any error and returns NULL. This saves you from your bad data messing up your query. After that, the query is pretty much as you had tried earlier. I truncate the timestamp to the hour in the inner query and then use that to group by in the outer query (Only using the rows which don't have NULL timestamps...meaning they didn't error)
I use the following query to get my data counted on hourly base:
select to_char(trunc(time, 'HH'), 'DD/MM/YY HH24') as "date",
count(event), count(distinct id) from source
where time >= date '2021-01-01'
group by trunc(time,'HH')
order by trunc(time,'HH');
What I now want to do is the same but on minute base. How can I get this done?
To me, you could have avoided trunc entirely as you use TO_CHAR anyway:
select to_char(time, 'dd/mm/yy hh24') ...
If you want to include minutes, no problem:
select to_char(time, 'dd/mm/yy hh24:mi') as "date",
count(event), count(distinct id)
from source
where ...
group by to_char(time, 'dd/mm/yy hh24:mi')
Note that sorting by strings probably won't produce desired results. Perhaps, if you'd change date format to e.g. 'yyyymmdd hh24:mi'
I have written query to get data for a particular day, but need a query to get the data on hourly and daily basis
My Query:
SELECT
TRAN_USERTRANSACTIONS.APPLICATIONNUMBER
FROM
TRAN_USERTRANSACTION
WHERE TRAN_USERTRANSACTIONS.CREATEDAT
LIKE '%19-09-19%'
GROUP BY
TRAN_USERGTRANSACTION.APPLICATIONNUMBER;
CREATEDAT is Timestampin in format as follows :DD-MM-YY hh.mm.ss.ssss AM/PM
By hour(hope this helps):
Select TRAN_USERTRANSACTIONS.APPLICATIONNUMBER
, TO_CHAR(TRAN_USERTRANSACTIONS.CREATEDAT ,'HH AM')
from TRAN_USERTRANSACTION
WHERE TRAN_USERTRANSACTIONS.CREATEDAT LIKE '%19-09-19%'
group by TRAN_USERTRANSACTIONS.APPLICATIONNUMBER
, TO_CHAR(TRAN_USERTRANSACTIONS.CREATEDAT ,'HH AM')
order by TO_CHAR(dat_azu,'HH AM') asc;
I assume you want a summary by hour and not by application. If so, the hour should be in the GROUP BY:
SELECT TO_CHAR(t.CREATEDAT, 'YYYY-MM-DD HH24') as dh,
COUNT(*)
FROM TRAN_USERTRANSACTION t
WHERE t.CREATEDAT >= DATE '2019-09-19' AND
t.CREATEDAT < DATE '2019-09-20'
GROUP BY TO_CHAR(t.CREATEDAT, 'YYYY-MM-DD HH24')
ORDER BY dh;
I have a column of type DATE stored data are contains date and time . I can see value when i do
select CAST(MSG_DT AS TIMESTAMP) from table;
this is the output
17-MAR-08 15:38:59,000000000
I have to select the row using
Only date
select CAST(MSG_DT AS TIMESTAMP) from
MWRB_RECEIVE where
MSG_DT >= TO_DATE( '2000-02-03' ,'YYYY-MM-DD')
and
MSG_DT <= TO_DATE( '2010-02-03' ,'YYYY-MM-DD')
Only time (eg: every message between 12:00:11 and 23:02:55)
In DB2 i can do
SELECT *
FROM TABLE
WHERE DATE(INS_TMS) = '2014-02-18'
SELECT *
FROM TABLE
WHERE TIME(INS_TMS) > '09.55.00'
In ORACLE I can't see the equivalent.
Try this:
SELECT *
FROM your_table
WHERE TO_CHAR (start_date, 'yyyy-mm-dd') = '2014-10-06'
AND TO_CHAR (start_date, 'hh24:mi:ss') > '10:00:00'
Why are you casting the column value to a TIMESTAMP when the column in the database is a DATE type? The fractional part of the seconds will always be 0, as DATE only has resolution to the seconds value. You need to add the hours,minutes, and seconds format specifier to the query:
select MSG_DT from
MWRB_RECEIVE
where MSG_DT between TO_DATE( '2000-02-03 12:00:11' ,'YYYY-MM-DD HH24:MI:SS') AND
TO_DATE( '2010-02-03 23:02:55' ,'YYYY-MM-DD HH24:MI:SS')
There is no need to split date and hour, you can have it in a single where clause
where field > to_date('20121212 12:12:12, 'YYYYMMDD HH24:MI:SS')
Check for your reference oracle to_date() as it seems the only thing you need
Assuming this has a simple solution, but I can't find it.
I'm trying to do some logic on a DATE field in Oracle. My desire is to take a DATE field and subtract X hours from it.
For instance: SELECT A.MyDATE - 100 Hours from dual;
however, I need a result in a timestamp format 'YYYY-MM-DD hh:mm'.
I've tried CAST(A.MyDATE as TIMESTAMP) - NUMTODSINTERVAL(100/24,'day') however it didn't work.
I found out that the issue is that the MyDATE field when cast to a timestamp still contained some residual time elements. How can I reset these??
Thanks!
You can just do this with subtraction:
select a.MyDate - 100.0/24
To convert to varchar:
select to_char(a.MyDate - 100.0/24, 'YYYY-MM-DD')
And, if you want to get rid of that pesky time on the date:
select trunc(a.MyDate - 100.0/24) as JustTheDate
The formats and dates in my example can be changed to any other formats and dates:
SELECT To_Timestamp(To_Char(Sysdate - INTERVAL '100' HOUR, 'MM/DD/YYYY HH24:MI'), 'MM/DD/YYYY HH24:MI')
FROM dual
/
Output:
2/4/2013 10:18:00.000000000 AM
To remove time element add Trunc() to any of your dates...:
SELECT Trunc(To_Timestamp(To_Char(Sysdate - INTERVAL '100' HOUR, 'MM/DD/YYYY HH24:MI'), 'MM/DD/YYYY HH24:MI'))
FROM dual
/
Output: 2/4/2013
Conversion/Casting - when using other dates in place of sysdate then add formats as in my other examples:
SELECT CAST(SYSDATE AS TIMESTAMP) - INTERVAL '100' HOUR FROM dual
/
Output: 2/4/2013 10:26:35.000000000 AM
SELECT start_date tstamp_to_date, CAST(start_date AS timestamp) date_to_tstamp FROM
(
SELECT to_date(to_char(to_timestamp ('2013-02-07 10:07:47.000' , 'YYYY-MM-DD HH24:MI:SS.FF'),'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS') start_date
FROM dual
)
/
Output:
tstamp_to_date date_to_tstamp
-------------------------------------------------------
2/7/2013 10:07:47 AM 2/7/2013 10:07:47.000000 AM
In Oracle, a DATE always has a day and a time component. Depending on the tool you are using and your session's NLS_DATE_FORMAT, it is entirely possible that the tool may not display the time component when you look at the data. But that is simply a display question, it has no impact on the actual data.
If you want to subtract 100 hours from midnight on the day that MyDate represents
SELECT TRUNC(MyDate) - interval '100' hour
FROM dual
This will return a DATE. If you want to return a string in a particular format
SELECT TO_CHAR( TRUNC(MyDate) - interval '100' hour, 'YYYY-MM-DD hh:mi am' )
FROM dual
Note that I'm assuming that there was a typo in your question. I assume that you want to display the minutes after the hour (mi) rather than the month (mm).
I am trying to fetch the records which is older than 30 days (from Mod_date) and I am using the below query and it is returning all the data and I want only 30 days old data.
Sample :- Mod_date 03-NOV-12 12.00.00.000000000 AM
Query :-
select Mod_date from fil_cnfact where Mod_date <= sysdate -30 order by Mod_date asc ;