我有一个很难从SQL Server将存储过程到Oracle有我们的产品与之兼容。
我有返回基于时间戳一些表的最新记录,查询:
SQL服务器:
SELECT TOP 1 *
FROM RACEWAY_INPUT_LABO
ORDER BY t_stamp DESC
=>将返回我的最新记录
但是, 甲骨文:
SELECT *
FROM raceway_input_labo
WHERE rownum <= 1
ORDER BY t_stamp DESC
=>将返回我最早的记录(可能取决于指数),无论ORDER BY
语句!
我封装在Oracle查询这种方式来满足我的要求:
SELECT *
FROM
(SELECT *
FROM raceway_input_labo
ORDER BY t_stamp DESC)
WHERE rownum <= 1
和它的作品。 但是,这听起来像一个可怕的黑客对我来说,尤其是当我有很多的相关表中的记录。
什么是实现这一目标的最佳途径?
在where
声明得到执行之前 order by
。 所以,你想要查询说:“ 拿第一排,然后命令它 t_stamp
递减 ”。 而这是不是你想要的东西。
子查询的方法是在Oracle这样做的正确方法。
如果你想在这两个服务器协同工作的一个版本,你可以使用:
select ril.*
from (select ril.*, row_number() over (order by t_stamp desc) as seqnum
from raceway_input_labo ril
) ril
where seqnum = 1
外*
将在最后一列返回“1”。 您将需要单独列出列,以避免这种情况。
使用ROW_NUMBER()
来代替。 ROWNUM
是一个伪列和ROW_NUMBER()
是一个函数。 您可以了解它们之间的差异,请参阅下面的查询输出的区别:
SELECT * FROM (SELECT rownum, deptno, ename
FROM scott.emp
ORDER BY deptno
)
WHERE rownum <= 3
/
ROWNUM DEPTNO ENAME
---------------------------
7 10 CLARK
14 10 MILLER
9 10 KING
SELECT * FROM
(
SELECT deptno, ename
, ROW_NUMBER() OVER (ORDER BY deptno) rno
FROM scott.emp
ORDER BY deptno
)
WHERE rno <= 3
/
DEPTNO ENAME RNO
-------------------------
10 CLARK 1
10 MILLER 2
10 KING 3
另一种我会在这个用例建议是使用MAX(t_stamp),以获得最新的行...例如
select t.* from raceway_input_labo t
where t.t_stamp = (select max(t_stamp) from raceway_input_labo)
limit 1
我的编码模式的偏好(也许) - 可靠,通常在执行或高于试图从分类列表中选择第1行更好 - 也是其目的是更明确的可读性。
希望这可以帮助 ...
SQLer
记录与这对夫妻的设计问题在上述评论。 短篇小说,在Oracle中,你需要的时候你有大的表和/或表与相同的列名手动限制的结果(和你不想显式类型逐一测试,并重新命名他们全部)。 简单的解决办法是要弄清楚你的断点,并限制在您的查询。 或者你也可以做到这一点的内查询,如果你没有冲突列名的约束。 例如
WHERE m_api_log.created_date BETWEEN TO_DATE('10/23/2015 05:00', 'MM/DD/YYYY HH24:MI')
AND TO_DATE('10/30/2015 23:59', 'MM/DD/YYYY HH24:MI')
将显着地减少的结果。 然后,你可以ORDER BY甚至做外部查询限制行。
另外,我觉得TOAD有一个特点,以限制行; 但是,不知道,没有在Oracle实际查询中限制。 不确定。
只需使用ROWNUM像下面
select *
from (select t.*
from raceway_input_labo ril
order by t_stamp desc
)
where rownum = 1