I have a DB table that contains x million rows and a new row is created regularly (multiple per second).
There is a timestamp column but no date recorded. However, there is a unique ID assigned to each row entry and I'd like to be able to run a select query that allows me to select every 10th row where the unique ID is greater than the one entered so it gives me a snap shot of every 10th record greater than a unique ID value rather than the whole table (so using the unique ID value as a variable)
I have put together the query below but this pulls out every 10th row from the entire table and then gives me the ones where the UNIQUEID is greater than 33188498698899117300014
SELECT ID, TRANSTIMESTAMP, GLOBTIME, REMTIME
from (select ID as rn, t.*
from TEST_TRANS t
) t
where rn - trunc(rn/10)*10 = 0 AND UNIQUEID > '33188498698899117300014'
ORDER BY ID DESC;
But this isn't exactly what I need as I need every 10th row greater than UNIQUEID '33188498698899117300014'
I'm sure this is straightforward but think I've hit a brick wall so any help would be much appreciated.
You want to filter in the inner query and use the ROW_NUMBER
analytic function to number the rows and then filter in the outer query to get every 10th row:
SELECT ID,
TRANSTIMESTAMP,
GLOBTIME,
REMTIME
FROM (
SELECT ID,
TRANSTIMESTAMP,
GLOBTIME,
REMTIME,
ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM TEST_TRANS
WHERE UNIQUEID > '33188498698899117300014'
)
WHERE MOD(rn, 10) = 0
ORDER BY ID DESC
Or, from Oracle 12:
SELECT ID,
TRANSTIMESTAMP,
GLOBTIME,
REMTIME
FROM TEST_TRANS
WHERE UNIQUEID > '33188498698899117300014'
ORDER BY MOD(ROW_NUMBER() OVER (ORDER BY id), 10),
id DESC
FETCH FIRST 10 PERCENT ROWS ONLY
Which, for the sample data:
CREATE TABLE test_trans (ID PRIMARY KEY, TRANSTIMESTAMP, GLOBTIME, REMTIME, UNIQUEID UNIQUE) AS
SELECT LEVEL,
TIMESTAMP '1970-01-01 00:00:00' + LEVEL * INTERVAL '1' SECOND,
TIMESTAMP '1970-01-01 00:00:00' + LEVEL * INTERVAL '1' SECOND,
TIMESTAMP '1970-01-01 00:00:00' + LEVEL * INTERVAL '1' SECOND,
TO_CHAR(
CASE
WHEN MOD(LEVEL, 10) IN (3, 4, 5, 7, 8)
THEN 33188498698899117300014 + LEVEL
ELSE 10000000000000000000000 + LEVEL
END
)
FROM DUAL
CONNECT BY LEVEL <= 100;
Both output:
ID | TRANSTIMESTAMP | GLOBTIME | REMTIME |
---|---|---|---|
98 | 1970-01-01 00:01:38.000000000 | 1970-01-01 00:01:38.000000000 | 1970-01-01 00:01:38.000000000 |
78 | 1970-01-01 00:01:18.000000000 | 1970-01-01 00:01:18.000000000 | 1970-01-01 00:01:18.000000000 |
58 | 1970-01-01 00:00:58.000000000 | 1970-01-01 00:00:58.000000000 | 1970-01-01 00:00:58.000000000 |
38 | 1970-01-01 00:00:38.000000000 | 1970-01-01 00:00:38.000000000 | 1970-01-01 00:00:38.000000000 |
18 | 1970-01-01 00:00:18.000000000 | 1970-01-01 00:00:18.000000000 | 1970-01-01 00:00:18.000000000 |