当用户选择查看最新记录的选项时,我需要显示最近的记录。我有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')
答案 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-join
,engine 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
...
我怀疑通过更好地理解您的数据模型和查询,可能会有更好的解决方案。但根据提供的信息,我认为上述内容应该会产生您正在寻找的结果。