我坚持使用我的SQL / Oracle查询..
对于此问题,感兴趣的字段为effective_day
(td.ws_date),ot.valid_from
和ot.valid_to.
每个effective_day
都会返回一条记录。只要在effective_day
之前或之后以及effective_day
之后或之后编辑该记录,该记录就有效。
要了解它何时有效,我们会查看字段ot.valid_from
和ot.valid_to.
ot.valid_from <= effective_day <= ot.valid_to
order_no
可以在一天内多次更新 - valid_to
和valid_from
字段会相应更新。所以三天内一个订单的更新可能是这样的:
ID |Order | Valid From | Valid To |
=================================================================
0 |112 | 07-SEP-11 21:13:12 | 08-SEP-11 01:02:11 |
1 |112 | 08-SEP-11 01:02:12 | 08-SEP-11 01:14:12 |
2 |112 | 08-SEP-11 01:14:13 | 09-SEP-11 05:23:51 |
3 |112 | 09-SEP-11 05:23:52 | 09-SEP-11 16:21:13 |
4 |112 | 09-SEP-11 16:21:14 | null |
如果我想退回effective_day = 08-SEP-11
的订单。返回的数据应该是当天最近更新的数据。所以它应该是ID 2。
同样,如果我想返回effective_day = 09-SEP-11
的订单明细,则应返回ID 4.
这是我的SQL
SELECT
td.ws_date effective_date,
ot.ORDER_NO,
ot.PROCESS_AREA,
ot.VALID_FROM,
ot.VALID_UNTIL
FROM ws_tracker_dates_tab td, ws_tracker_old_tab ot
WHERE (ot.VALID_FROM <= td.WS_DATE)
AND (ot.VALID_UNTIL IS NULL or (ot.VALID_UNTIL>=td.ws_date))
AND ot.COMPLETED = 'N'
AND td.WS_DATE BETWEEN (SYSDATE -30) AND (SYSDATE)
AND ot.process_area is not null
任何帮助都将不胜感激。
答案 0 :(得分:0)
为避免此类问题,请使用将来的日期(如31-DEC-9999
)作为当前有效/有效条目的“有效期”。
这样,您始终可以使用between()
找到最新条目。此外ORDER BY
也会正常运作。
如果您无法更改此设置,请创建一个视图,将null
替换为您选择的日期:
select ..., coalesce(valid_to, to_timestamp('31-DEC-9999', 'DD-MON-YYYY')), ....
答案 1 :(得分:0)
在where子句中使用子查询,如下所示
Where ot.ID =
(select max(in1.ID)
from ws_tracker_old_tab in1 where in1.Order=ot.Order
and in1.VALID_FROM = (select max(in2.VALID_FROM)
from ws_tracker_old_tab in2
where in2.Order =in1.Order
and in2.VALID_FROM <= td.WS_DATE
and (in2.VALID_UNTIL IS NULL or in2.VALID_UNTIL>=td.ws_date))
如果您知道每个订单的VALID_FROM日期总是唯一的,那么您可以更简单一点:
Where ot.VALID_FROM = (select max(in1.VALID_FROM)
from ws_tracker_old_tab in1
where in1.Order = ot.Order
and in1.VALID_FROM <= td.WS_DATE
and (in1.VALID_UNTIL IS NULL or in1.VALID_UNTIL>=td.ws_date))
答案 2 :(得分:0)
处理valid_from
和valid_to
的最简单方法(尤其是考虑到valid_to
可能为空[可能意味着可能意味着什么]),是忽略valid_to
:因为在这种情况下,它是一个派生的值(不是通常应该存储在数据库中的东西)。
那就是说,我相信以下内容适合你:
WITH max_stamp(effective_date, order_no, stamp) as (
SELECT a.ws_date, b.order_no, b.MAX(b.valid_from)
FROM ws_tracker_dates_tab a
JOIN ws_tracker_old_tab b
ON b.valid_from < CAST((a.ws_date + INTERVAL '1' DAY) AS TIMESTAMP)
WHERE a.ws_date BETWEEN (SYSDATE - 30) AND (SYSDATE)
GROUP BY a.ws_date, b.order_no)
SELECT a.*, b.effective_date
FROM ws_tracker_old_tab a
JOIN max_stamp b
ON b.stamp = a.valid_from
AND b.order_no = a.order_no
请注意我在DB2上,并且没有使用过Oracle,因此可能需要进行一些调整。