SQL:为每个不同的元素选择最旧的记录

时间:2019-02-18 22:20:41

标签: sql oracle

我为措辞不佳表示歉意,让我先说明一下

这是表格:

select task_id, task_status, date_change, username from logs
order by task_id, date_change

结果:

 TASK_ID    TASK_STATUS DATE_CHANGE     USERNAME    

1   101     Green       2019/01/03      Camille 
2   101     Blue        2019/01/07      Lucas
3   101     Green       2019/01/09      Rudy

4   102     Blue        2019/01/03      Lucas
5   102     Green       2019/01/04      Delphine

6   103     Yellow      2019/01/07      Penelope
7   103     Green       2019/01/11      Rudy
8   103     Blue        2019/01/14      Delphine
9   103     Green       2019/01/18      Camille

10  104     Blue        2019/01/08      Rudy
11  104     Green       2019/01/10      Camille
12  104     Green       2019/01/14      Penelope

我有几个任务,每个任务可以具有不同的状态。 对于每个任务,我要提取状态最早的绿色状态。

所以在这种情况下,结果将是:

    TASK_ID TASK_STATUS DATE_CHANGE     USERNAME
1   101     Green       2019/01/03      Camille 
2   102     Green       2019/01/04      Delphine
3   103     Green       2019/01/11      Rudy
4   104     Green       2019/01/10      Camille

这是我最接近解决方案的地方:

select task_id, task_status, date_change, username
from logs
where task_status =('Green')
and task_id = ('101')
and date_change = (
    select min(date_change)
    from logs 
    where task_status = ('Green') and task_id =('101')
)

这根本不好,我必须对每个任务进行查询,这完全不切实际。

是否可以使用一种变量,并通过类似以下方式更改最后一行:

and date_change = (
    select min(date_change)
    from logs 
    where task_status = ('Green') and task_id =($CURRENT_TASK_ID)
)

或者也许是另一种完全解决该问题的方法?

非常感谢您的宝贵时间。

3 个答案:

答案 0 :(得分:0)

尝试一下:

select * from logs l
where Date_Change = (
    select min(DATE_CHANGE) from logs li 
    where li.task_id = l.task_id and li.task_Status = l.task_status )
  and TASK_STATUS = 'Green';

答案 1 :(得分:0)

您只需要group by task_id并获得最小的date_change:

select task_id, 'Green' task_status, min(date_change) date_change
from logs
where task_status = 'Green'
group by task_id

对于特定的task_id = '101',您不需要分组:

select '101' task_id, 'Green' task_status, min(date_change) date_change
from logs
where task_status = 'Green' and task_id = '101'

答案 2 :(得分:0)

在Oracle中,使用 analytic functions (又称为窗口函数)可以非常有效地实现这一目标。在此用例中,export const login = (username, password) => ({ [RSAA]: { endpoint: '/api/auth/token/obtain/', method: 'POST', body: JSON.stringify({username, password}), headers: { 'Content-Type': 'application/json' }, types: [ LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE ] } }) 是您的朋友:

ROW_NUMBER()

内部查询为具有相同SELECT * FROM ( SELECT l.*, ROW_NUMBER() OVER(PARTITION BY task_id ORDER BY date_change) rn FROM logs l WHERE ASK_STATUS = 'Green' ) x WHERE rn = 1 task_id的组中的每个记录分配一个数字,最早的记录具有数字task_status。您可以运行子查询以查看结果。然后,外部查询会在每组的第一条记录中进行过滤。

从早期版本(8i)开始,

窗口功能在Oracle中可用。他们通常会在效率方面击败聚合和子查询。