Выберите строки, когда значение столбца между датами в Oracle? - PullRequest
0 голосов
/ 28 сентября 2018

Например, у меня есть данные таблицы А, как показано ниже:

ID  Code    Date
1   A   19-Feb-18
1   B   18-Feb-18
1   B   17-Feb-18
1   B   16-Feb-18
2   A   17-Feb-18
2   B   16-Feb-18
3   A   17-Feb-18
3   A   16-Feb-18
4   D   16-Feb-18

Теперь я хочу получить результат, подобный:

case 1 : Если мне нужны данные между *От 1008 * до 19-feb-18, тогда результат должен быть примерно таким:

1   A   19-Feb-18
1   B   18-Feb-18
1   B   17-Feb-18
1   B   16-Feb-18
2   A   17-Feb-18
2   B   16-Feb-18

, он исключит запись для Id 3 и 4, поскольку в данной дате нет изменений.

case 2: если мне нужны данные в диапазоне от 16-feb-18 до 18-feb-18, результат должен быть примерно таким:

2   A   17-Feb-18
2   B   16-Feb-18

, это исключит запись для идентификаторов 1,3 и 4, поскольку в данной дате нет изменений.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Вы можете использовать аналитическую функцию COUNT( DISTINCT code ) OVER ( PARTITION BY id ), чтобы получить ответ, используя только одно сканирование таблицы:

Скрипка SQL

Настройка схемы Oracle 11g R2:

CREATE TABLE table_name ( ID, Code, "DATE" ) AS
SELECT 1, 'A', DATE '2018-02-19' FROM DUAL UNION ALL
SELECT 1, 'B', DATE '2018-02-18' FROM DUAL UNION ALL
SELECT 1, 'B', DATE '2018-02-17' FROM DUAL UNION ALL
SELECT 1, 'B', DATE '2018-02-16' FROM DUAL UNION ALL
SELECT 2, 'A', DATE '2018-02-17' FROM DUAL UNION ALL
SELECT 2, 'B', DATE '2018-02-16' FROM DUAL UNION ALL
SELECT 3, 'A', DATE '2018-02-17' FROM DUAL UNION ALL
SELECT 3, 'A', DATE '2018-02-16' FROM DUAL UNION ALL
SELECT 4, 'D', DATE '2018-02-16' FROM DUAL;

Запрос 1 :

SELECT ID,
       Code,
       "DATE"
FROM   (
  SELECT t.*,
         COUNT( DISTINCT code ) OVER ( PARTITION BY id ) AS num_changes
  FROM   table_name t
  WHERE  "DATE" BETWEEN DATE '2018-02-16'
                    AND DATE '2018-02-19'
)
WHERE num_changes > 1

Результаты :

| ID | CODE |                 DATE |
|----|------|----------------------|
|  1 |    A | 2018-02-19T00:00:00Z |
|  1 |    B | 2018-02-18T00:00:00Z |
|  1 |    B | 2018-02-17T00:00:00Z |
|  1 |    B | 2018-02-16T00:00:00Z |
|  2 |    A | 2018-02-17T00:00:00Z |
|  2 |    B | 2018-02-16T00:00:00Z |

Запрос 2 :

SELECT ID,
       Code,
       "DATE"
FROM   (
  SELECT t.*,
         COUNT( DISTINCT code ) OVER ( PARTITION BY id ) AS num_changes
  FROM   table_name t
  WHERE  "DATE" BETWEEN DATE '2018-02-16'
                    AND DATE '2018-02-18'
)
WHERE num_changes > 1

Результаты :

| ID | CODE |                 DATE |
|----|------|----------------------|
|  2 |    A | 2018-02-17T00:00:00Z |
|  2 |    B | 2018-02-16T00:00:00Z |
0 голосов
/ 28 сентября 2018

Вот один из вариантов (вам нужно 12 строк и более):

SQL> with test (id, code, datum) as
  2  (select 1, 'a', date '2018-02-19' from dual union all
  3   select 1, 'b', date '2018-02-18' from dual union all
  4   select 1, 'b', date '2018-02-17' from dual union all
  5   select 1, 'b', date '2018-02-16' from dual union all
  6   select 2, 'a', date '2018-02-17' from dual union all
  7   select 2, 'b', date '2018-02-16' from dual union all
  8   select 3, 'a', date '2018-02-17' from dual union all
  9   select 3, 'a', date '2018-02-16' from dual union all
 10   select 4, 'd', date '2018-02-16' from dual
 11  )
 12  select id, code, datum
 13  from test
 14  where id in (select id
 15               From test
 16               where datum between date '2018-02-16' and date '2018-02-18'
 17               group by id
 18               having count(distinct code) > 1)
 19  order by id, datum desc;

        ID C DATUM
---------- - ----------
         2 a 17.02.2018
         2 b 16.02.2018

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