sql - выбрать несколько максимальных значений для заказа по - PullRequest
0 голосов
/ 21 мая 2019

У меня есть date, work, Tasks в таблице. на каждый date у нас есть несколько записей по одной записи на Task. В данный день, если есть 3 задачи, у нас будет 3 записи

Я хочу брать последние задания за каждую работу. следующий запрос дал мне все

SELECT task
FROM TEST_RESULTS 
WHERE RESULT ='PASSED' and
      task NOT IN (' ', 'N/A' )
ORDER BY work, date DESC  ;

Я могу получить только отсортированный список. Может ли кто-нибудь помочь мне получить строки с самой поздней датой для каждой работы.

Требуется образец вывода:

+ -----+-------+------------+
| work | task  | date       |
+ -----+-------+------------+
| 1    | clean | 1-jan-2018 |
| 1    | brush | 1-jan-2018 |
| 2    | wash  | 2-jan-2018 |
| 2    | clean | 2-jan-2018 |
| 3    | xyz   | 1-jan-2018 |
| 3    | ccc   | 1-jan-2018 |
+ -----+-------+------------+

Ответы [ 4 ]

1 голос
/ 21 мая 2019

используйте row_numner() аналитическую функцию

select work,date
    from 
    (
    select work,date,row_number()over(partition by work order by date desc ) rn
    from  TEST_RESULTS 
    WHERE RESULT ='PASSED' and task NOT IN (' ','N/A' )
    ) a where a.rn=1

, если вам нужна только последняя дата всей задачи, используйте простой подзапрос

with cte as 

(
select * ,max(date) over(partition by work) as mxdate
from TEST_RESULTS
where RESULT ='PASSED' and task NOT IN (' ','N/A' )
)  select * from cte where  
   date=mxdate
0 голосов
/ 21 мая 2019

Установка Oracle :

CREATE TABLE test_results ( work, task, "date", result ) AS
SELECT 1, 'clean', DATE '2018-01-01', 'PASSED' FROM DUAL UNION ALL
SELECT 1, 'brush', DATE '2018-01-01', 'PASSED' FROM DUAL UNION ALL
SELECT 2, 'wash',  DATE '2018-01-01', 'PASSED' FROM DUAL UNION ALL -- duplicate with older date
SELECT 2, 'wash',  DATE '2018-01-02', 'PASSED' FROM DUAL UNION ALL
SELECT 2, 'clean', DATE '2018-01-02', 'PASSED' FROM DUAL UNION ALL
SELECT 2, 'brush', DATE '2018-01-01', 'PASSED' FROM DUAL UNION ALL -- Not the latest date
SELECT 3, 'xyz',   DATE '2018-01-01', 'PASSED' FROM DUAL UNION ALL
SELECT 3, 'ccc',   DATE '2018-01-01', 'PASSED' FROM DUAL;

Запрос 1 : Если вы хотите установить самую последнюю date для каждой пары work / task, тогда:

SELECT work,
       task,
       MAX( "date" ) AS "date"
FROM   TEST_RESULTS 
WHERE  RESULT ='PASSED'
AND    task NOT IN (' ', 'N/A' )
GROUP BY work, task
ORDER BY work, "date" DESC;

Выход :

WORK | TASK  | date     
---: | :---- | :--------
   1 | brush | 01-JAN-18
   1 | clean | 01-JAN-18
   2 | wash  | 02-JAN-18
   2 | clean | 02-JAN-18
   2 | brush | 01-JAN-18
   3 | xyz   | 01-JAN-18
   3 | ccc   | 01-JAN-18

Запрос 2 : если вы хотите, чтобы task только для последних dateдля каждого work затем:

SELECT work,
       task,
       "date"
FROM   (
  SELECT work,
         task,
         "date",
         MAX( "date" ) OVER ( PARTITION BY work ) AS latest_date
  FROM   TEST_RESULTS 
  WHERE  RESULT ='PASSED'
  AND    task NOT IN (' ', 'N/A' )
)
WHERE  "date" = latest_date
ORDER BY work, task;

Выход :

WORK | TASK  | date     
---: | :---- | :--------
   1 | brush | 01-JAN-18
   1 | clean | 01-JAN-18
   2 | clean | 02-JAN-18
   2 | wash  | 02-JAN-18
   3 | ccc   | 01-JAN-18
   3 | xyz   | 01-JAN-18

db <> скрипка здесь

0 голосов
/ 21 мая 2019

Если вы просто хотите выполнить задачу, вы можете использовать агрегацию с keep в Oracle:

SELECT work,
       MAX(task) KEEP (DENSE_RANK FIRST ORDER BY date DESC) as most_recent_task,
       MAX(date)
FROM TEST_RESULTS 
WHERE RESULT = 'PASSED' and
      task NOT IN (' ', 'N/A' )
GROUP BY work;
0 голосов
/ 21 мая 2019

Если вам нужна последняя задача для каждой работы, вам нужна одна строка результатов для каждой работы, поэтому вы должны GROUP BY work. Вы можете получить последнюю задачу с помощью Oracle KEEP LAST.

.
SELECT work, MAX(task) KEEP (DENSE_RANK LAST ORDER BY date) AS last_task
FROM test_results 
WHERE result = 'PASSED' 
AND task NOT IN (' ', 'N/A')
GROUP BY work
ORDER BY work;
...