我正在尝试查询表格。该表包含条形码和与条形码相关的活动,特别是在移动条形码时和其中。我正在尝试为每个条形码返回一条记录,其中包含与位置一起移动的最后日期和时间。我目前有MAX围绕移动日期和时间。以下是重复行的示例。
BarCode Location Date Time
000055279 1 EWC 03-APR-14 12:30:44
000055279 1 G-T 05-AUG-14 08:16:10
000055279 1 TBD 20-AUG-14 08:32:14
我只想要此示例中的最后一行(000055279 1 TBD 20-AUG-14 08:32:14
)。目前的查询基本上是:
SELECT DISTINCT "BarCode", "Location", MAX("Date"), MAX("Time")
FROM TABLE1
一旦我添加了位置,就会发生重复。
提前致谢。
答案 0 :(得分:3)
有几种选择。一种是使用row_number()
:
select *
from (
select barcode, location, date, time,
row_number() over (partition by barcode order by date desc, time desc) rn
from table1
) t
where rn = 1
答案 1 :(得分:2)
根据您的想法,但修复设计中的缺陷,您可以(重新)使用CTE生成正确的 datetime 列,然后查询该视图:
WITH V AS (SELECT "BarCode", "Location", TO_DATE("Date"|| ' ' || "Time", 'DD-MON-YY HH:MI:SS') "datetime" FROM TABLE1) SELECT "BarCode", "Location", MAX("datetime") FROM V GROUP BY "BarCode", "Location"
未测试。小心拼写错误!
话虽如此,但就我自己而言,我会推动表格中只有一个DATE
列。如果由于某种原因不可行,也许您可以建议添加虚拟列:
ALTER TABLE TABLE1
ADD ("datetime" DATE GENERATED ALWAYS
AS (TO_DATE("Date"|| ' ' || "Time", 'DD-MON-YY HH:MI:SS')) VIRTUAL);
答案 2 :(得分:0)
Oracle ROW_NUMBER分析功能是您所需要的。 Oracle documentation解释得很好,这是一个有用的例子,使用你的数据和一些额外的条形码来说明它在更现实的数据集中工作。我正在连接日期&时间列并使用TO_DATE获取正确的日期。由于这些是保留字,因此用双引号括起来。
SQL> create table barcode_activity (
2 barcode varchar2(20),
3 location varchar2(10),
4 "date" varchar2(10),
5 "time" varchar2(10)
6 );
Table created.
SQL>
SQL> insert into barcode_activity
2 values
3 ( '000055279 1','EWC', '03-APR-14','12:30:44')
4
SQL> insert into barcode_activity
2 values
3 ( '000055279 1','G-T', '05-APR-14','08:16:10');
1 row created.
SQL>
SQL> insert into barcode_activity
2 values
3 ( '000055279 1','TBD', '20-APR-14', '08:32:14');
1 row created.
SQL>
SQL> insert into barcode_activity
2 values
3 ( '000009999 1','TBD', '20-APR-14', '07:42:32');
1 row created.
SQL>
SQL> insert into barcode_activity
2 values
3 ( '000001234 1','TBD', '29-APR-14', '17:22:18');
1 row created.
SQL>
SQL> insert into barcode_activity
2 values
3 ( '000001234 1','TBD', '29-APR-14', '17:22:18');
1 row created.
SQL>
SQL> insert into barcode_activity
2 values
3 ( '000001234 1','TBD', '29-APR-14', '17:22:18');
1 row created.
SQL> commit;
Commit complete.
SQL>
SQL> SELECT * FROM barcode_activity ORDER BY 1,2,3;
BARCODE LOCATION date time
-------------------- ---------- ---------- ----------
000001234 1 TBD 29-APR-14 17:22:18
000001234 1 TBD 29-APR-14 17:22:18
000001234 1 TBD 29-APR-14 17:22:18
000009999 1 TBD 20-APR-14 07:42:32
000055279 1 G-T 05-APR-14 08:16:10
000055279 1 TBD 20-APR-14 08:32:14
6 rows selected.
SQL>
SQL> /* rank solution
SQL> this will return one row
SQL> for all barcodes in the table where there are collisions in rank th
SQL> multiple rows are returned
SQL> */
SQL> SELECT barcode, location, "date", "time"
2 FROM
3 (SELECT barcode,
4 location,
5 "date",
6 "time",
7 RANK() OVER (
8 PARTITION BY barcode
9 ORDER BY TO_DATE("date"||' '||"time",'DD-MON-YYYY HH24:MI:SS') DESC
10 ) AS activity_order
11 FROM barcode_activity)
12 WHERE activity_order = 1;
BARCODE LOCATION date time
-------------------- ---------- ---------- ----------
000001234 1 TBD 29-APR-14 17:22:18
000001234 1 TBD 29-APR-14 17:22:18
000001234 1 TBD 29-APR-14 17:22:18
000009999 1 TBD 20-APR-14 07:42:32
000055279 1 TBD 20-APR-14 08:32:14
SQL>
SQL> /* row_number solution - works regardless of collisions */
SQL> SELECT barcode, location, "date", "time"
2 FROM
3 (SELECT barcode,
4 location,
5 "date",
6 "time",
7 row_number() OVER (
8 PARTITION BY barcode
9 ORDER BY TO_DATE("date"||' '||"time",'DD-MON-YYYY HH24:MI:SS') DESC
10 ) AS activity_order
11 FROM barcode_activity)
12 WHERE activity_order = 1;
BARCODE LOCATION date time
-------------------- ---------- ---------- ----------
000001234 1 TBD 29-APR-14 17:22:18
000009999 1 TBD 20-APR-14 07:42:32
000055279 1 TBD 20-APR-14 08:32:14