仅显示最近的记录

时间:2015-09-04 04:17:40

标签: sql oracle oracle10g

当用户选择查看最新记录的选项时,我需要显示最近的记录。我有3个不同的表格,我从中获取数据并在屏幕上显示。

以下是创建的示例表。

Create table one(sealID integer,product_ser_num varchar2(20),create_time timestamp,status varchar2(10));


create table two(transID integer,formatID integer, formatStatus varchar,ctimeStamp timestamp,sealID integer);

create table three(transID integer,fieldStatus varchar,fieldValue varchar,exctype varchar);

我正在加入3张桌子并在一个屏幕上显示结果。我想根据时间戳显示最新记录。 请在3个不同的表格中找到屏幕上的样本数据。

ProductSerialNumber  formatID formatStatus  fieldStatus TimeStamp
 ASD100               100       P               P        2015-09-03 10:30:22
 ASD100               200       p               P        2015-09-03 10:30:22
 ASD100               100       p               P        2015-09-03 10:22:11
 ASD100               200       p               P        2015-09-03 10:22:11

我想显示上面显示的表中的最新记录,这些记录应返回前2行,因为它们是使用timestamp列检查时的最新记录。

请建议对以下查询进行哪些更改以显示最近的记录。

SELECT transId,product_ser_num,status, to_char(timestamp, 'yyyy-mm-dd hh24:mi:ss') timestamp, 
                      cnt   
                     FROM (SELECT one.*,
                  row_number() over(ORDER BY 
                  CASE             
                  WHEN :orderDirection like '%asc%' THEN
                   CASE
                      WHEN :orderBy='product_ser_num' THEN product_ser_num,
                      WHEN :orderBy='status' THEN status  
                      WHEN :orderBy='timestamp' THEN to_char(timestamp, 'yyyy-mm-dd hh24:mi:ss') 
                          ELSE to_char(timestamp, 'yyyy-mm-dd hh24:mi:ss') 
                   END
                              END ASC,   
                                  CASE  
                    WHEN :orderDirection like '%desc%' THEN  
                    CASE 
                    WHEN :orderBy='product_ser_num' THEN product_ser_num, 
                                    WHEN :orderBy='status' THEN status 
                                    WHEN :orderBy='timestamp' THEN to_char(timestamp, 'yyyy-mm-dd hh24:mi:ss') 
                                    ELSE to_char(timestamp, 'yyyy-mm-dd hh24:mi:ss') 
                                  END          
                               END DESC , transId ASC) line_number 
                               FROM (select one_inner.*, COUNT(1) OVER() cnt 
                  from (select two_tran.transaction_id,
                                  one_res.product_serial_number productSerialNumber,
                                  one_res.status status,from one one_res
                                  left outer join two two_trans on two_trans.sealID = one_res.sealID
                                  left outer join three three_flds on two_tran.transID = three_flds.transID and (three_flds.fieldStatus = 'P') 

4 个答案:

答案 0 :(得分:1)

我不认为您正在寻找 Top-n 查询,因为您的主题标题显示了这一点。

您似乎希望以自定义顺序显示数据,如第一张图片中所示。您希望在timestamp的基础上将三行集合在一起。

我准备了一个小测试用例来演示行的自定义顺序:

SQL> WITH DATA(ID, num, datetime) AS(
  2  SELECT 10, 1001, SYSDATE     FROM dual UNION ALL
  3  SELECT 10, 6009, SYSDATE     FROM dual UNION ALL
  4  SELECT 10, 3951, SYSDATE     FROM dual UNION ALL
  5  SELECT 10, 1001, SYSDATE -1  FROM dual UNION ALL
  6  SELECT 10, 6009, SYSDATE -1  FROM dual UNION ALL
  7  SELECT 10, 3951, SYSDATE -1  FROM dual
  8  )
  9  SELECT ID,
 10    num,
 11    TO_CHAR(DATETIME, 'yyyy-mm-dd hh24:mi:ss') TIMESTAMP
 12  FROM
 13    (SELECT t.*,
 14      row_number() OVER(ORDER BY DATETIME DESC,
 15      CASE num
 16        WHEN 1001
 17        THEN 1
 18        WHEN 6009
 19        THEN 2
 20        WHEN 3951
 21        THEN 3
 22      END, num) rn
 23    FROM DATA t
 24    );

        ID        NUM TIMESTAMP
---------- ---------- -------------------
        10       1001 2015-09-04 11:04:48
        10       6009 2015-09-04 11:04:48
        10       3951 2015-09-04 11:04:48
        10       1001 2015-09-03 11:04:48
        10       6009 2015-09-03 11:04:48
        10       3951 2015-09-03 11:04:48

6 rows selected.

现在,您可以看到,对于相同的 ID 10 NUM 值会按自定义顺序进行分组。

答案 1 :(得分:0)

这个查询看起来非常庞大和复杂,所以这可能过于简单了:

在末尾添加一个子句limit 3

答案 2 :(得分:0)

我认为你需要做的是:

 $("#type_wrap > input").prop('disabled', true);

这基本上会为您提供所需的行,但不是所有元数据。

因此,您只需要select max(timestamp), engine_serial_number, formatID from < joins here > group by engine_serial_number, formatID 使用主要联接来获取其余信息(加入所有三列,re-joinengine serial number)。

这应该有效。

希望这有帮助!

答案 3 :(得分:0)

很难给出准确的答案,因为您的查询不完整。但是我会给你一般的想法,你可以将它调整到你的查询中。

实现目标的一种方法是使用dense_rank()分析函数按时间戳按降序对行进行编号(在这种情况下也可以使用rank(),它不会实际上很重要)。具有相同时间戳的所有行将被分配相同的&#34; rank&#34;,因此您可以按等级过滤以仅获取最新记录。

尝试将您的查询调整为以下内容:

select ...
  from (select ...,
               dense_rank() over (order by timestamp desc) as timestamp_rank
          from ...)
 where timestamp_rank = 1
 ...

我怀疑通过更好地理解您的数据模型和查询,可能会有更好的解决方案。但根据提供的信息,我认为上述内容应该会产生您正在寻找的结果。