Complicated SQL query
679732Jan 14 2009 — edited Jan 15 2009Hello all.
I'm relatively new to SQL, and having a little trouble developing an SQL query for an application I am developing.
The application I am writing is intended to do processing of log entries stored in a database by a web application. Log entries are stored in a Log table, details of the web app's resources are stored in a Resource table, and logs entries related to a user accessing a particular resource are mapped to the resource in question using a ResourceLog join table. Note that log entries may relate to other things as well, not just resource accesses. The definition of these tables follows.
bq. create table Log \\ (bq. logId integer not null, \\ userId integer not null, \\ logTime date not null
);
create table Resource
(
bq. resourceId integer not null, \\ access varchar2(20) not null
);
create table ResourceLog
(
bq. logId integer not null, \\ resourceId integer not null
);
Whenever a user accesses a resource, it is logged using the Log and ResourceLog tables. I need to determine the time difference between each access of a "restricted" resource and the chronologically next log entry (of any kind) for the user. As such, I'm trying to format a query that returns columns consisting of the log ID of the restricted resource access, the user's ID, the time of the restricted resource access, the ID of the resource accessed, and the time of the next log entry. I can get the first four of these using a query something like the following:
bq. select l1.logId, l1.userId, l1.logTime, r.resourceId from Log l1 join ResourceLog rl on rl.logId = l1.logId join Resource r on r.resourceId = rl.resourceId where r.accessl = 'restricted'
Or, alternatively:
bq. select l1.logId, l1.userId, l1.logTime, r.resourceId from Log l1, ResourceLog rl, Resource r where r.access = 'restricted' and rl.resourceId = r.resourceId and l1.logId = rl.logId
As far as I can tell both of the above are functionally equivalent, so what is the difference (if any) and which is preferable?
Additionally, for each access of a restricted resource, if I know the time the user accessed the restricted resource (an l1.logTime), I think I can get the time of the next log entry something like the following (meant more like pseudocode than actual SQL):
bq. select * from (select l2.logTime from Log l2 where l2.logTime >= l1.logTime and l2.userId = l1.userId and l2.logId l1.logId order by l2.dt asc) where rownum = 1
My second problem is I cannot manage to figure out how to combine the two into a single query. I assume it is possible, but am not sure.
Any help would be greatly appreciated!
Thanks!