所以我目前有一种方法可以做我想做的事情:
SELECT * FROM
( SELECT
e.*,
ROW_NUMBER() OVER (partition by USER_ID order by COPIED_TIMESTAMP DESC) r
FROM
TABLE e)
WHERE r = 1;
这很好用,但如果表变大,我觉得可能存在性能问题。我在看这样的事情:
SELECT MAX(COPIED_TIMESTAMP), USER_ID
FROM TABLE
GROUP BY USER_ID
这也有效,但有没有办法显示所有信息,而不仅仅是时间戳和ID。我对SQL / Oracle查询很陌生,在这个问题上有点迷失。
答案 0 :(得分:1)
但如果表格变大,我觉得可能存在性能问题。
我认为分析查询很好,因为它只会扫描一次。您可以通过创建索引(如果需要)来进一步优化其性能。
您的第二个查询将仅返回timestamp和user_id列,但是,当您需要其他列时,无论如何都要执行多个表扫描。所以,这不是一个好主意。
如果您正在寻找其他选项,例如 NOT EXISTS ,则仍需要多次表扫描。
让我们看一个小测试用例:
分析查询
SQL> EXPLAIN PLAN FOR SELECT * FROM
2 (SELECT e.*,
3 ROW_NUMBER() OVER (partition BY deptno order by hiredate DESC) r
4 FROM emp e
5 ) WHERE r = 1;
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 3291446077
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 1400 | 3 (0)| 00:00:01 |
|* 1 | VIEW | | 14 | 1400 | 3 (0)| 00:00:01 |
|* 2 | WINDOW SORT PUSHED RANK| | 14 | 518 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 14 | 518 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("R"=1)
2 - filter(ROW_NUMBER() OVER ( PARTITION BY "DEPTNO" ORDER BY
INTERNAL_FUNCTION("HIREDATE") DESC )<=1)
17 rows selected.
SQL>
NOT EXISTS查询
SQL> EXPLAIN PLAN FOR
2 SELECT *
3 FROM emp t1
4 WHERE NOT EXISTS (SELECT 1 FROM emp t2
5 WHERE t1.deptno = t2.deptno
6 and t2.hiredate > t1.hiredate);
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 3353202012
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 48 | 6 (0)| 00:00:01 |
|* 1 | HASH JOIN ANTI | | 1 | 48 | 6 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 14 | 518 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 14 | 154 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."DEPTNO"="T2"."DEPTNO")
filter("T2"."HIREDATE">"T1"."HIREDATE")
16 rows selected.
SQL>
因此,您可以看到分析查询仅执行一次表扫描。
答案 1 :(得分:0)
返回not exists
相同ID的行以及更晚的时间戳:
SELECT USER_ID, COPIED_TIMESTAMP, other_column1, other_column2
FROM TABLE t1
WHERE NOT EXISTS (select 1 from table t2
where t1.user_id = t2.user_id
and t2.COPIED_TIMESTAMP > t1.COPIED_TIMESTAMP)
答案 2 :(得分:0)
Analytic functions是你的朋友:
SELECT MAX( COPIED_TIMESTAMP ) KEEP ( DENSE_RANK LAST ORDER BY COPIED_TIMESTAMP ) AS COPIED_TIMESTAMP,
MAX( other_column ) KEEP ( DENSE_RANK LAST ORDER BY COPIED_TIMESTAMP ) AS other_column,
MAX( other_column2 ) KEEP ( DENSE_RANK LAST ORDER BY COPIED_TIMESTAMP ) AS other_column2,
USER_ID
FROM TABLE_NAME
GROUP BY USER_ID