sql - Oracle:当一列中的值更改时选择行
问题描述
我有下表:
PLACE USER_ID Date
---------- ---------- -----------------------------
ABC 4 14/04/20 12:05:29,255000000
ABC 4 14/04/20 15:42:28,389000000
ABC 4 14/04/20 18:33:20,202000000
ABC 4 14/04/20 22:51:28,339000000
XYZ 4 14/04/20 11:07:23,335000000
XYZ 2 14/04/20 12:15:12,123000000
ABC 4 13/04/20 22:09:33,255000000
QWE 4 13/04/20 10:18:29,144000000
XYZ 2 14/04/20 10:05:47,255000000
当地点更改我选择的 user_id 的日期顺序时,我需要获取行。 所以想要的结果应该是这样的(对于 user_id 4):
PLACE USER_ID DATE
---------- ---------- -----------------------------
ABC 4 14/04/20 12:05:29,255000000
XYZ 4 14/04/20 11:07:23,335000000
ABC 4 13/04/20 22:09:33,255000000
QWE 4 13/04/20 10:18:29,144000000
我尝试使用最小日期,但在我的示例中,如果用户回到那个地方,我会丢失数据:
SELECT MIN(DATE), PLACE FROM user_places WHERE USER_ID=4 GROUP BY PLACE
结果我得到(缺少一行):
PLACE USER_ID DATE
---------- ---------- -----------------------------
XYZ 4 14/04/20 11:07:23,335000000
ABC 4 13/04/20 22:09:33,255000000
QWE 4 13/04/20 10:18:29,144000000
提前致谢!
解决方案
match_recognize
在 Oracle 12.1 及更高版本中,像这样的间隙和孤岛问题对于该子句来说是一件容易的事。例如:
表设置
alter session set nls_timestamp_format = 'dd/mm/rr hh24:mi:ss,ff';
create table user_places (place, user_id, date_) as
select 'ABC', 4, to_timestamp('14/04/20 12:05:29,255000000') from dual union all
select 'ABC', 4, to_timestamp('14/04/20 15:42:28,389000000') from dual union all
select 'ABC', 4, to_timestamp('14/04/20 18:33:20,202000000') from dual union all
select 'ABC', 4, to_timestamp('14/04/20 22:51:28,339000000') from dual union all
select 'XYZ', 4, to_timestamp('14/04/20 11:07:23,335000000') from dual union all
select 'XYZ', 2, to_timestamp('14/04/20 12:15:12,123000000') from dual union all
select 'ABC', 4, to_timestamp('13/04/20 22:09:33,255000000') from dual union all
select 'QWE', 4, to_timestamp('13/04/20 10:18:29,144000000') from dual union all
select 'XYZ', 2, to_timestamp('14/04/20 10:05:47,255000000') from dual
;
commit;
查询输出
select place, user_id, date_
from (select * from user_places where user_id = 4)
match_recognize (
order by date_
all rows per match
pattern (a {- b* -} )
define b as place = a.place
)
order by date_ desc -- if needed
;
PLACE USER_ID DATE_
----- ------- ---------------------------
ABC 4 14/04/20 12:05:29,255000000
XYZ 4 14/04/20 11:07:23,335000000
ABC 4 13/04/20 22:09:33,255000000
QWE 4 13/04/20 10:18:29,144000000
这里有几点需要注意:
DATE
是保留关键字。不是一个好的列名。我DATE_
改用了;注意结尾的下划线。- 我硬编码了值4。当然,更好的做法是把它变成一个绑定变量。
- 如果您真的一次只需要这样做
user_id
,那么执行我所做的最有效 - 首先在子查询中过滤行。但是,如果您需要对同一查询中的所有用户 ID 执行此操作,则不需要子查询;您从表本身中选择,并且您需要在子句partition by user_id
顶部的右侧添加 before 。match_recognize
order by date_
推荐阅读
- javascript - mac-os:无法在 Firefox chrome 中运行量角器测试,它的工作正常
- go - 杜松子酒框架可以获取像`map[string]interface{}`这样的json post数据而不是与struct绑定吗?
- java - 无法使用 Scandit SDK 扫描某些条码 - Android
- python - Folium - 如何在可见的平移地图上调用 get_bounds()
- powershell - 加速 PowerShell 的测试连接
- android - Firestore 中的默认值
- javascript - 未捕获的 ReferenceError:fn_get_data_oneid 未在 HTMLDivElement.onclick 中定义
- java - 拍摄照片的亮度问题(Xamarin.Android)
- arduino - DHT22 和 ESP32 - 湿度不工作且温度错误
- c# - 将操作绑定到 MenuItem 模板内的 Checkbox Checked 事件