Sql 每个代码的ORACLE最小日期行

Sql 每个代码的ORACLE最小日期行,sql,oracle,greatest-n-per-group,Sql,Oracle,Greatest N Per Group,我有两张桌子 以前的信息 ╔══════════╦══════════════╦═════════════╦══════════════════╦════════════╗ ║ previ_id ║ code_station ║ code_modele ║ date_previ ║ type_previ ║ ╠══════════╬══════════════╬═════════════╬══════════════════╬════════════╣ ║ 501201 ║

我有两张桌子

以前的信息

╔══════════╦══════════════╦═════════════╦══════════════════╦════════════╗
║ previ_id ║ code_station ║ code_modele ║    date_previ    ║ type_previ ║
╠══════════╬══════════════╬═════════════╬══════════════════╬════════════╣
║   501201 ║         2952 ║          48 ║ 29/01/2017 15:00 ║ AUTO       ║
║   501156 ║         2952 ║          48 ║ 30/01/2017 07:00 ║ AUTO       ║
╚══════════╩══════════════╩═════════════╩══════════════════╩════════════╝
PREVI_VAL

╔══════════╦═══════════════╦═════════════════════╦══════════════╗
║ previ_id ║ code_scenario ║        temps        ║ valeur_debit ║
╠══════════╬═══════════════╬═════════════════════╬══════════════╣
║   501201 ║            -1 ║ 30/01/2017 10:00:00 ║ 2,024        ║
║   501201 ║            -1 ║ 30/01/2017 13:00:00 ║ 2,215        ║
║   501201 ║             0 ║ 30/01/2017 10:00:00 ║ 1,456        ║
║   501201 ║             0 ║ 30/01/2017 13:00:00 ║ 1.687        ║
╚══════════╩═══════════════╩═════════════════════╩══════════════╝
查询

对于给定的编码模式,我需要获取最接近的上一个值,以获得编码场景列表

我现在所拥有的:

SELECT *
FROM (
  SELECT previ_id, type_previ
  FROM (
    SELECT previ_id, type_previ
    FROM PREVI.previ_info
    WHERE code_modele = '48'
    ORDER BY date_previ DESC
  ) pi
  WHERE ROWNUM < 2
) pi
JOIN PREVI.previ_val pv
ON pv.previ_id = pi.previ_id
期望的结果

╔══════════╦════════════╦═══════════════╦═════════════════════╦════════════════════╗
║ previ_id ║ type_previ ║ code_scenario ║        temps        ║    valeur_debit    ║
╠══════════╬════════════╬═══════════════╬═════════════════════╬════════════════════╣
║   501201 ║ AUTO       ║ -1            ║ 30/01/2017 13:00:00 ║ 2,289291759560228  ║
║   501201 ║ AUTO       ║ 0             ║ 30/01/2017 13:00:00 ║ 2,281620351009415  ║
╚══════════╩════════════╩═══════════════╩═════════════════════╩════════════════════╝
这给了我下一个日期的行。如果是2017年1月30日12:45,我需要2017年1月30日13:00:00而不是10:00:00的行。 代码来自一个列表。目前它仅为0和-1

如何改进查询以使其正常工作

对于给定的代码模型,我需要获得代码场景列表的最接近的上一个值

您可以使用
行号
分析功能。不清楚您是如何对数据进行分区的,但类似的方法应该可以工作:

SELECT *
FROM   (
  SELECT i.*,
         v.*,
         ROW_NUMBER() OVER ( PARTITION BY i.previ_id, v.code_scenario
                             ORDER BY ABS( i.date_previ - v.temps ) ) AS rn
  FROM   ( SELECT *
           FROM   ( SELECT *
                    FROM   PREVI_INFO
                    WHERE  i.code_modele = 48
                    ORDER BY date_previ DESC )
           WHERE ROWNUM = 1
         ) i
         INNER JOIN PREVI_VAL v
         ON ( i.previ_id = v.previ_id )
)
WHERE rn = 1;
更新

我需要知道下一个与现在相比的日期

这将连接
temps
值位于
SYSDATE
之后的表,然后按时间顺序获取第一个:

SELECT *
FROM   (
  SELECT i.*,
         v.*,
         ROW_NUMBER() OVER ( PARTITION BY i.previ_id, v.code_scenario
                             ORDER BY v.temps ) AS rn
  FROM   ( SELECT *
           FROM   ( SELECT *
                    FROM   PREVI_INFO
                    WHERE  i.code_modele = 48
                    ORDER BY date_previ DESC )
           WHERE ROWNUM = 1
         ) i
         INNER JOIN PREVI_VAL v
         ON (   i.previ_id = v.previ_id 
            AND v.temps >= SYSDATE )
)
WHERE rn = 1;

你能解释一下“最近的”吗?截止日期?之前之后?我试着在期望的结果之后解释它。我需要知道下一个与现在相比的日期。这可以理解吗?现在你指的是sysdate?sysdate,或者我可以把它放在一个where close中,并将它添加到我的java代码中。这个查询不起作用。例如,您正在从表
previ\u info
中获取
code\u场景
,而不是
previ\u val
+使用
code\u modele=xx
将我的Where条件放在哪里?第二个查询似乎工作正常。我在哪里可以添加我需要的代码场景
where code\u场景在(0,-1)
中作为包含联接的子查询的
where
子句,或作为
ON
子句。
SELECT *
FROM   (
  SELECT i.*,
         v.*,
         ROW_NUMBER() OVER ( PARTITION BY i.previ_id, v.code_scenario
                             ORDER BY v.temps ) AS rn
  FROM   ( SELECT *
           FROM   ( SELECT *
                    FROM   PREVI_INFO
                    WHERE  i.code_modele = 48
                    ORDER BY date_previ DESC )
           WHERE ROWNUM = 1
         ) i
         INNER JOIN PREVI_VAL v
         ON (   i.previ_id = v.previ_id 
            AND v.temps >= SYSDATE )
)
WHERE rn = 1;