[英]ROWNUMBER function in Oracle
小解释:
我有一个名为passes
的表,它与2个表( services
(cod_serv)和atend
(通过))链接在一起。 可以为不同的服务复制通行证。
例如:如果我有3个服务,那么对于同一服务,我可以有3个通过nº01, 但没有2个通过nº1(我在复合主键中定义了它)。
为了进行测试,我添加了102个通行证(所有情况都为“ F”且日期(今天)相同)。 然后,我为每个服务添加了34个通行证(我有3个服务)。
以下查询显示了schema
是如何定义的。
SELECT DISTINCT s.pass, s.data, cod_serv, situation, hour, min
FROM passes
JOIN atend a ON s.pass = a.pass;
PASS DATA COD_SERV S HOUR MIN
----- -------- --------- - ------- -------
04 26/03/16 2 F 12 24
04 26/03/16 1 F 13 27
13 26/03/16 1 F 14 26
18 26/03/16 3 F 14 27
18 26/03/16 2 F 14 28
15 26/03/16 1 F 14 29
10 26/03/16 3 F 14 30
... ... ... ... ... ...
然后,我想从特定日期获取第100次( ROWNUMBER()
)通过(如下图所示,其值为21),情况='F',按小时和分钟排序。
第100行:
21 26/03/16 3 F 14 34
以下query
未返回任何内容,我不知道为什么。 顺便说一句,在这种情况下,我有100多个通行证。
SELECT DISTINCT pass, data, cod_serv, situation FROM
(SELECT DISTINCT a.pass, s.data, cod_serv, situation,
ROW_NUMBER() OVER(PARTITION BY situation, hour, min
ORDER BY situation, hour, min) row
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE situation = 'F' AND
TRUNC(a.data) = TRUNC('some date'))
WHERE row = 100;
编辑:
我目前的查询:
SELECT DISTINCT pass, cod_serv FROM
(SELECT DISTINCT s.pass, cod_serv,
ROW_NUMBER() OVER(PARTITION BY TRUNC(s.data)
ORDER BY a.hour, a.min) row
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F' AND
TRUNC(s.data) = TRUNC(SYSDATE))
WHERE row = 100;
在OVER
子句的PARTITION BY
和ORDER BY
中具有相同的字段几乎没有意义。
PARTITION BY
子句应列出定义从1开始对记录进行计数的组的字段。
ORDER BY
子句定义该组中记录的计数顺序。
在您撰写时:
我想从特定日期获得第100次(
ROWNUMBER()
)传递,情况='F',按小时和分钟排序
...您实际上是在说这些条款中需要写的内容:
ROW_NUMBER() OVER(PARTITION BY data, situation ORDER BY hour, min)
因此,您的主要错误是将小时和分钟放在PARTITION BY
子句中,一旦发现分钟差,就使记录计数从1开始,大多数记录的编号为1。
编辑
似乎没有选择时,Oracle不会保留相同的row
号。 这可能是因为ORDER BY hour, min
不确定。 无论是什么原因,都可以通过选择外部查询中的row
来解决:
SELECT pass, row FROM ( ... etc ...) WHERE row = 100
如果只需要通过,则可以再次包装该查询:
SELECT pass FROM (
SELECT pass, row FROM ( ... etc ...) WHERE row = 100
)
这个怎么样?
首先,在执行row_number()
之前,应用所有过滤器(因为您不想计算要过滤掉的行):
SELECT s.pass, s.data, cod_serv, s.situation, a.hour, a.min
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F'
AND TRUNC(s.data) = TRUNC(SYSDATE)
现在,将其包装在外部查询中,在其中应用row_number()
:
SELECT pass, data, cod_serv, situation, hour, min,
rowseq=row_number() over (order by hour, min)
FROM (
SELECT s.pass, s.data, cod_serv, s.situation, a.hour, a.min
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F'
AND TRUNC(s.data) = TRUNC(SYSDATE)
) t1
最后,将其包装在外部查询中,在其中将过滤器应用于“一百”条记录:
SELECT pass, data, cod_serv, situation, hour, min
FROM (
SELECT pass, data, cod_serv, situation, hour, min,
rowseq=row_number() over (order by hour, min)
FROM (
SELECT s.pass, s.data, cod_serv, s.situation, a.hour, a.min
FROM passes s
JOIN atend a ON s.pass = a.pass
WHERE s.situation = 'F'
AND TRUNC(s.data) = TRUNC(SYSDATE)
) t1
WHERE rowseq = 100
最后,如果任何部分需要调整(不同的过滤器,联接等),则可以自行运行这些内部查询级别中的每一个,以检查中间结果,以确保最终结果是所需的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.