как получить если значение не в oracle сгруппировать по - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть таблица с именем statustimeline, структура которой имеет вид

id | applicationid | status | createdon
---+---------------+--------+----------
11 |1              |4       |     
---+---------------+--------+----------
10 |1              |3       |
---+---------------+--------+----------
9  |1              |2       |
---+---------------+--------+----------
8  |1              |1       |
---+---------------+--------+----------
7  |2              |3       |
---+---------------+--------+----------
6  |2              |2       |
---+---------------+--------+----------
5  |2              |1       |
---+---------------+--------+----------
4  |3              |5       |
---+---------------+--------+----------
3  |3              |3       |
---+---------------+--------+----------
2  |3              |2       |
---+---------------+--------+----------
1  |3              |1       |
---+---------------+--------+----------

Если я разделю ее по идентификатору приложения, будет три группы.

select applicationid,ngstatus, row_number() over (partition by applicationid order by id desc) rownumbr 
from applicationstatustimeline ;

Я хочу выбрать только те applicationid, чья группа никогда не имела статус = 4 (applicationid = 2 и applicationid = 3 в этом случае)

есть ли какая-либо функция?

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

Почему бы не простой minus оператор множества?

SQL> with statustimeline (id, applicationid, status) as
  2    -- sample data
  3    (select 11, 1, 4 from dual union all
  4     select 10, 1, 3 from dual union all
  5     select  9, 1, 2 from dual union all
  6     select  8, 1, 1 from dual union all
  7     select  7, 2, 3 from dual union all
  8     select  6, 2, 2 from dual union all
  9     select  5, 2, 1 from dual union all
 10     select  4, 3, 5 from dual union all
 11     select  3, 3, 3 from dual union all
 12     select  2, 3, 2 from dual union all
 13     select  1, 3, 1 from dual
 14    )
 15  -- query you need
 16  select applicationid
 17    from statustimeline
 18  minus
 19  select applicationid
 20    from statustimeline
 21    where status = 4;

APPLICATIONID
-------------
            2
            3

SQL>
0 голосов
/ 16 апреля 2020

Еще один вариант - использовать NOT EXISTS следующим образом:

SELECT *
  FROM STATUSTIMELINE S
 WHERE S.STATUS <> 4
   AND NOT EXISTS (
        SELECT 1
          FROM STATUSTIMELINE S4
         WHERE S4.STATUS = 4
           AND S.APPLICATIONID = S4.APPLICATIONID
    );

Еще один вариант - использовать NOT IN следующим образом:

SELECT *
  FROM STATUSTIMELINE S
 WHERE S.STATUS <> 4
   AND S.APPLICATIONID NOT IN (
        SELECT S4.APPLICATIONID
          FROM STATUSTIMELINE S4
         WHERE S4.STATUS = 4
    )
0 голосов
/ 16 апреля 2020

Если вы хотите использовать здесь функции analyti c, мы можем использовать COUNT:

WITH cte AS (
    SELECT t.*,
        COUNT(CASE WHEN status = 4 THEN 1 END) OVER (PARTITION BY applicationid) AS four_cnt
    FROM applicationstatustimeline t
)

SELECT id, applicationid, status, createdon
FROM cte
WHERE four_cnt = 0;

В приведенном выше CTE мы генерируем вычисляемый столбец four_cnt, значение которого будет идентичным для каждой группы applicationid записей. Это значение будет равно нулю при условии, что status=4 никогда не встречается, в противном случае это будет некоторое значение, большее нуля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...