SQL: выберите самую старую запись для каждого отдельного элемента - PullRequest
0 голосов
/ 19 февраля 2019

Я прошу прощения за плохой заголовок, позвольте мне проиллюстрировать сначала

Вот таблица:

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 голосов
/ 19 февраля 2019

Вам нужно только 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'
0 голосов
/ 19 февраля 2019

В Oracle это может быть достигнуто очень эффективно, используя аналитические функции , также известные как оконные функции.Для этого варианта использования 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, причем самая ранняя запись имеет номер 1.Вы можете запустить подзапрос, чтобы увидеть результаты.Затем внешние запросы фильтруют в первой записи в каждой группе.

Оконные функции доступны в Oracle с ранних версий (8i).Они обычно превосходят агрегацию и подзапросы с точки зрения эффективности.

0 голосов
/ 19 февраля 2019

Попробуйте это:

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';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...