Sql 如何根据两个不同的属性选择最新的行?
我需要为我的员工选择以下交易(109、154、982、745)的最新活动代码(A、V、W、J)。我需要知道我的员工的上一笔交易(从列表中)有哪些活动代码。有两个表涉及员工ID上的联接。 表1: 表2:Sql 如何根据两个不同的属性选择最新的行?,sql,database,oracle,Sql,Database,Oracle,我需要为我的员工选择以下交易(109、154、982、745)的最新活动代码(A、V、W、J)。我需要知道我的员工的上一笔交易(从列表中)有哪些活动代码。有两个表涉及员工ID上的联接。 表1: 表2: |Emp_id | date | act_code | trans | 1 | 1/1/17 | A | 109 | 1 | 3/4/12 | X | 203 | 1 |
|Emp_id | date | act_code | trans
| 1 | 1/1/17 | A | 109
| 1 | 3/4/12 | X | 203
| 1 | 2/14/09 | A | 154
| 2 | 1/1/17 | A | 110
| 2 | 6/6/13 | V | 109
| 3 | 12/13/16 | J | 982
| 3 | 11/23/14 | W | 745
| 4 | 12/13/16 | X | 154
| 4 | 11/23/14 | W | 745
我想回报的是:
|Emp_id | STUFF | date | act_code | trans
| 1 | stuff | 1/1/17 | A | 109
| 3 | stuff | 12/13/16 | J | 982
不会选择Emp 2,因为最新的trans不是正确的值之一。不会选择Emp 4,因为最新的act_代码不是正确的值之一。有人知道怎么做吗?提前感谢。使用
第一个值
获取act\u code、trans的最新值,然后检查它们是否在指定列表中
select * from (
select distinct t1.emp_id,t1.stuff,
max(t2.date) over(partition by t2.emp_id) as latest_date,
first_value(t2.act_code) over(partition by t2.emp_id order by t2.date desc) as latest_act_code,
first_value(t2.trans) over(partition by t2.emp_id order by t2.date desc) as latest_trans
from tbl1 t1
join tbl2 t2 on t1.emp_id=t2.emp_id
) t
where latest_act_code in ('A','V','W','J') and latest_trans in (109, 154, 982, 745)
这里有一个方法
使用ROW_NUMBER()
按emp_id
对行进行分区,并按日期对行进行排序:
SELECT t2.emp_id, t1.stuff, t2.date, t2.act_code, t2.trans,
ROW_NUMBER() over (PARTITION BY t2.emp_id ORDER BY t2.date DESC) RN
FROM Table1 t1
JOIN Table2 t2 on t1.emp_id = t2.emp_id;
然后使用外部选择将其筛选到列表中包含值的最新记录(RN=1
):
SELECT emp_id, stuff, date, act_code, trans
FROM (
SELECT t2.emp_id, t1.stuff, t2.date, t2.act_code, t2.trans,
ROW_NUMBER() over (PARTITION BY t2.emp_id ORDER BY t2.date DESC) RN
FROM Table1 t1
JOIN Table2 t2 on t1.emp_id = t2.emp_id
) A
WHERE RN = 1
AND trans IN (109, 154, 982, 745)
AND act_code IN ('A', 'V', 'W', 'J');
emp 2具有最新的值a
。为什么不应选择它?因为事务是110(不在列表中)Hi,感谢您的评论。这似乎给了我想要的结果!不过我有一个简短的问题。这将返回最新的act代码和trans。是否有办法在2016年1月10日之后返回相同的数据?(我应该在最初的问题中加上这个,这是我的疏忽。)@user7002207不用担心,很乐意帮忙。当你说在2016年1月10日之后,你的意思是你不想看到记录,除非最新记录是在2016年1月10日之后?如果是这样,您只需将和日期>'20161001'
添加到外部选择过滤器。我不确定我是否理解这一点。
SELECT emp_id, stuff, date, act_code, trans
FROM (
SELECT t2.emp_id, t1.stuff, t2.date, t2.act_code, t2.trans,
ROW_NUMBER() over (PARTITION BY t2.emp_id ORDER BY t2.date DESC) RN
FROM Table1 t1
JOIN Table2 t2 on t1.emp_id = t2.emp_id
) A
WHERE RN = 1
AND trans IN (109, 154, 982, 745)
AND act_code IN ('A', 'V', 'W', 'J');