Find out whether values exists in other table within time range - sql

I'm trying to evaluate whether a user's action is performed in relativity to another action. Both actions are marked with a timestamp.
What I want to evaluate is whether a user when she has an entry in one table e.g. A (both tables has the same ID for an individual user) has an entry in another table, B, in between the time of entry in A and 5 minutes earlier. I manage to extract time for all values
SELECT
TO_CHAR(playdatetime - 5/(24*60),'YYYY-MM-DD HH24:MI:SS') five_min_future,
TO_CHAR(playdatetime,'YYYY-MM-DD HH24:MI:SS') jetzt,
TO_CHAR(SEARCHDATE,'YYYY-MM-DD HH24:MI:SS') ses_time
I tried to make something like this:
CASE
WHEN TO_CHAR(SEARCHDATE,'YYYY-MM-DD HH24:MI:SS')
BETWEEN TO_CHAR(playdatetime - 1/(24*60),'YYYY-MM-DD HH24:MI:SS')
AND
TO_CHAR(playdatetime,'YYYY-MM-DD HH24:MI:SS')
THEN 1
ELSE 0
END timediff
but how could I get this to just check for one user and not just evaluate the row at hand?

The following query shows records that exist in both a and b, where the record in b occurs up to 5 minutes before that in a:
select a.user_id,
a.event_dt,
b.event_dt
from a
join b
on b.user_id = a.user_id
and b.event_dt between (a.event_dt - (5 / (60 * 24))) and a.event_dt;

Related

Group Timestamps into intervals of 5 minutes, take value that's closest to timestamp and always give out a value

I'm new to SQL coding and would heavily appreciate help for a problem I'm facing. I have the following SQL script, that gives me the following output (see picture 1):
WITH speicher as(
select a.node as NODE_ID, d.name_0 as NODE_NAME, d.parent as PARENT_ID, c.time_stamp as ZEITSTEMPEL, c.value_num as WERT, b.DESCRIPTION_0 as Beschreibung, TO_CHAR(c.time_stamp, 'HH24:MI:SS') as Uhrzeit
from p_value_relations a, l_nodes d, p_values b, p_value_archive c
where a.node in (select sub_node from l_node_relations r where r.node in (
50028,
49989,
49848
))
and a.node = d.id
and (b."DESCRIPTION_0" like 'Name1' OR b."DESCRIPTION_0" like 'Name2')
and c.time_stamp between SYSDATE-30 AND SYSDATE-1
and a.value = b.id and b.id = c.value)
SELECT WERT as Value, NODE_NAME, ZEITSTEMPEL as Timestamp, Uhrzeit as Time, Beschreibung as Category
FROM speicher
I would like to create time intervals of 5 minutes to output the value. It should always choose the value closest above one on the defined time interval time stamps. If there is no value inside a set 5 minute intervall it should still give out the last value it finds, since the value has not changed in that case. To see what I mean please see the following picture. Any help wold be greatly appreciated. This data is from an oracle database.
Result until now [
Result I would like
Since I do not understand your data, and can't test with it, I present something I could test with. My data has a table which tracks when folks login to a system.
This is not intended as a complete answer, but as something to potentially point you in the right direction;
with time_range
as
(
select rownum, sysdate - (1/288)*rownum time_stamp
from dual
connect By Rownum <= 288*30
)
select time_stamp, min(LOGIN_TIME)
from time_range
left outer join WEB_SECURITY_LOGGED_IN on LOGIN_TIME >= time_stamp
group by time_stamp
order by 1;
Good luck...
Edit:
The with part of the query builds a time_stamp column which has one row for every 5 minutes for the last 30 days. The query portion joins to my login log table which I get the login which is the smallest date/time greater than the time_stamp.

Timestamp filter in PLSQL

Let's say I have an table containing a user rating of movies like IMDB movie database.
ID
USER_REVIEW
USER_RATING
USER_ID
1
blub
10
1
2
blob
9
2
3
blab
7
3
These table inserts have been taken yesterday.
The entries with the id 1 and 2 have been taken between 16:00 and 16:10. The third entry with id 3 have been taken between 16:10 and 16:15 How can I find a select statement that filters me the first two entries between 16:00 and 16:10?
Or is it possible to find out which are the exact timestamps of the inserts from yesterday?
is it possible to find the exact timestamp of the inserts from yesterday?
Sure, if there's a timestamp column in the table.
As it looks as if such a column doesn't exist, a simple option to add it is
alter table movies add date_insert date default sysdate;
Oracle will auto-populate that column with SYSDATE (unless you explicitly insert it), which means that your current INSERT statement remains "as is", you don't have to change it a bit.
Then you'd - for example - select rows inserted yesterday as
select *
from movies
where trunc(date_insert) = trunc(sysdate - 1)
Or, as you asked, rows inserted yesterday (10th of August 2021) between 16:00 and 16:10:
select *
from movies
where date_insert between to_date('10.08.2021 16:00', 'dd.mm.yyyy hh24:mi')
and to_date('10.08.2021 16:10', 'dd.mm.yyyy hh24:mi')
try the GETDATE() function.
here is something to help you:
https://www.mssqltips.com/sqlservertip/1145/date-and-time-conversions-using-sql-server/

Oracle DB, for each row delete any similar timestamps in the table

I have a program recording timestamps when users connect to a program. However sometimes it likes to record the same connections multiple times, so I'll have duplicate entries that are half a second apart or less. I need an oracle query that can essentially look at the timestamp in each row and delete rows with a timestamp that is within 5 seconds of it. I'm not sure what the best way to approach this problem is, but due to technical limitations I'm trying to avoid scripting it. Any advice would be greatly appreciated.
Sample data looks something like this.
User, Timestamp
user1, 20-NOV-20 05.09.09.650146000 PM
user1, 20-NOV-20 05.09.11.764345432 PM
user2, 23-NOV-20 02.51.31.765432432 PM
user2, 23-NOV-20 02.51.32.355684235 PM
and I would want the query to trim it down to this.
user1, 20-NOV-20 05.09.09.650146000 PM
user2, 23-NOV-20 02.51.31.765432432 PM
If there were even more rows attributed to the same user close together it would get rid of them all. I imagine it would make look at each row and make a query to delete from UserSessions where timestamp <= (timestamp this row) + 5 seconds and timestamp >= (timestamp this row) - 5 seconds. But not where timestamp = (timestamp this row)
I have no idea what the syntax for this is or how do do the query per row.
Sample data and expected results would be helpful, particularly for various corner cases (several rows each within a few seconds of each other for example). Assuming you want to keep the latest row, something like this would work
delete from your_table earlier
where exists( select 1
from your_table later
where earlier.user_id = later.user_id
and later.login_date > earlier.login_date
and later.login_date <= earlier.login_date + interval '5' second )
Here's a liveSQL link using your sample data that shows the query producing the results you expect.
Hmmm . . . You seem to want to keep only rows where there is not a timestamp within 5 seconds before. I think that would be:
delete from t
where exists (select 1
from t t2
where t2.user_id = t.user_id and
t2.timetamp < t.timestamp and
t2.timestamp >= t.timestamp - interval '5' second
);

Discrepancy in counts - Oracle SQL group by query

I am trying to fetch the count of records between 3 PM and 4 PM. The first query returns 473 records whereas the second query returns 474 between 3 PM and 4 PM. Please can you let me know which one could be correct or what I need to do in order to identify the query that provides the accurate result?
select count(*)
from table
where start_ts between
to_timestamp('2017-03-06 15:00:00','YYYY-MM-DD HH24:MI:SS') and to_timestamp('2017-03-06 16:00:00','YYYY-MM-DD HH24:MI:SS')
select count(*),to_char(start_ts,'YYYY-MM-DD HH24')
from table
where start_ts between
to_timestamp('2017-03-06 00:00:00','YYYY-MM-DD HH24:MI:SS') and to_timestamp('2017-03-06 23:59:59','YYYY-MM-DD HH24:MI:SS')
group by to_char(start_ts,'YYYY-MM-DD HH24')
order by to_char(start_ts,'YYYY-MM-DD HH24')
Here is one guess. The first query is return 374 records and the second is returning two rows, one with 373 records and one with 1 record.
The 1 record has a time of exactly '2017-03-06 16:00:00', so it shows up in a different bin from the rest.
This seems like a plausible explanation, although it requires that the numbers be in the other order.

Orace/SQL multiple group by

I can't seem to get my head around this...
I have the following statement:
select aT.PieceNo, count(*)
from send_piece aT
where message_no in (7104, 7113)
and aT.Created > To_Timestamp('01-JAN-14 00:00:00', 'DD-MON-YY HH24:MI:SS')
group by aT.PieceNo;
In this grouped list, there will be many records with the same PieceNo AND aT.Created value. I need to show only these records.
I tried
group by aT.PieceNo, aT.Created;
but it seemed to reverse the initial grouping.
Table structured as follows: ID, Message_No, XML_Data, Created
I am extracting the PieceNo value from the XML_Data. The above query returns:
167408305E01 5
167408505C01 8
167408206A01 9
167408306A01 4
...
Each record within that group contains a Created value (DateTime). I need to show only the records that share the same Created value within those groups (if that makes sense?).
Basically, I'm trying to extract all the records in this table that share the same PieceNo and Created values.
select aT.PieceNo, aT.Created,count(*)
from send_piece aT
where message_no in (7104, 7113)
and aT.Created > To_Timestamp('01-JAN-14 00:00:00', 'DD-MON-YY HH24:MI:SS')
group by aT.PieceNo, aT.Created;