小解释:
我有一个名为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;
答案 0 :(得分:0)
在PARTITION BY
子句中的ORDER BY
和OVER
中使用相同的字段毫无意义。
PARTITION BY
子句应列出定义从1开始计算记录的组的字段。
ORDER BY
子句定义记录在该组内的计数顺序。
在你写的时候:
我希望从特定日期获得第100个(
ROWNUMBER()
)通过情况=' F'按小时和分钟排序
...你实际上用语言说出了这些条款需要加入的内容:
ROW_NUMBER() OVER(PARTITION BY data, situation ORDER BY hour, min)
所以你的主要错误是将小时和 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
)
答案 1 :(得分:0)
这个怎么样?
首先,在执行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
最后,如果需要调整任何部分(不同的过滤器,连接等),您可以自行运行每个级别的内部查询以检查中间结果,以确保最终结果就是你想要的。