Вычитание столбца на основе другого столбца - PullRequest
0 голосов
/ 13 июня 2018

Эта таблица состоит из данных транзакции, где каждая строка представляет собой одну транзакцию обмена.Основные собираемые данные: среднее количество лет, необходимое пользователям для перехода с чеков на кредитные карты при оплате .

Я пытаюсь вычесть год, когда человек впервые использовалпроверьте год, когда он впервые использовал кредитную карту для того же получающего банковского счета.Пример данных прилагается ниже.Этот запрос чертовски сложен, и мне интересно, должен ли я / могу ли я это сделать, но это то, что я получил до сих пор

SELECT 
    ID,
    BankAcc#,
FROM table
GROUP BY
    ID,
    BankAcc#,
    TransYear,
    Method
ORDER BY 
    ID,BackAcc#,TransYear ASC

Пример таблицы (извините, не удалось вставитьфотография, так как я новичок)

Моя идея состояла в том, чтобы сгруппировать ID-Bank # -TransYear-Method в одну строку, где TransYear был самым ранним годом этого метода, используя ORDER BY ASC LIMIT 1Проблемы, с которыми я сталкиваюсь:

  1. Oracle не поддерживает LIMIT после предложения ORDER BY.Я пытался использовать OFFSET или FETCH, но после предложения ORDER BY он почему-то не работал.У меня Oracle 12.9.0.71, поэтому теоретически должна иметь эту функцию , но нет.Я также пробовал WHERE rownum = 1, но он ограничивает все мои результаты 1 вместо ограничения группы ID-Bank-Year-Method до 1.
  2. Даже если мне удастся получить строки правильных данных, ядо сих пор не знаю, как я могу вычесть значения года чека против карты.Проблема заключается в том, что данные находятся в одном столбце, и мне нужно отличить их от другого столбца, прежде чем вычесть значения года.

Есть мысли?Цени любую помощь, тем более что это действительно сложно.

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Два метода - один с использованием MIN и CASE, а другой с использованием MIN и PIVOT

SQL Fiddle

Oracle11g Настройка схемы R2 :

CREATE TABLE table_name ( PersonId, BankAcc, TransactionNo, TransYear, method) as
  select 1, 10, 1,  2011, 'check' from dual union
  select 1, 10, 5,  2012, 'card'  from dual union
  select 2, 11, 7,  2012, 'check' from dual union
  select 2, 15, 10, 2012, 'check' from dual union
  select 2, 15, 11, 2014, 'card'  from dual union
  select 2, 15, 14, 2016, 'card'  from dual union
  select 2, 19, 15, 2009, 'check' from dual union
  select 2, 19, 16, 2015, 'card'  from dual union
  select 3, 20, 25, 2017, 'check' from dual union
  select 3, 21, 34, 2015, 'check' from dual union
  select 3, 21, 51, 2017, 'card'  from dual;

Запрос 1 :

SELECT   PersonID,
         BankAcc,
         MIN( CASE method WHEN 'card' THEN TransYear END )
           - MIN( CASE method WHEN 'check' THEN TransYear END ) AS diff
FROM     table_name
GROUP BY PersonID,
         BankAcc
ORDER BY PersonID,
         BankAcc

Результаты :

| PERSONID | BANKACC |   DIFF |
|----------|---------|--------|
|        1 |      10 |      1 |
|        2 |      11 | (null) |
|        2 |      15 |      2 |
|        2 |      19 |      6 |
|        3 |      20 | (null) |
|        3 |      21 |      2 |

Запрос 2 :

SELECT PersonId,
       BankAcc,
       crd - chk AS diff
FROM   ( SELECT PersonId, BankAcc, TransYear, method FROM table_name )
PIVOT( MIN( transyear ) FOR method IN ( 'check' AS chk, 'card' AS crd ) )
ORDER BY PersonID, BankAcc

Результаты :

| PERSONID | BANKACC |   DIFF |
|----------|---------|--------|
|        1 |      10 |      1 |
|        2 |      11 | (null) |
|        2 |      15 |      2 |
|        2 |      19 |      6 |
|        3 |      20 | (null) |
|        3 |      21 |      2 |
0 голосов
/ 13 июня 2018

Этот запрос возвращает результат, который вы опубликовали;посмотрите, действительно ли это нормально.

SQL> with test (person_id, acc, trans, tyear, method) as
  2    (select 1, 10, 1,  2011, 'check' from dual union
  3     select 1, 10, 5,  2012, 'card'  from dual union
  4     select 2, 11, 7,  2012, 'check' from dual union
  5     select 2, 15, 10, 2012, 'check' from dual union
  6     select 2, 15, 11, 2014, 'card'  from dual union
  7     select 2, 15, 14, 2016, 'card'  from dual union
  8     select 2, 19, 15, 2009, 'check' from dual union
  9     select 2, 19, 16, 2015, 'card'  from dual union
 10     select 3, 20, 25, 2017, 'check' from dual union
 11     select 3, 21, 34, 2015, 'check' from dual union
 12     select 3, 21, 51, 2017, 'card'  from dual
 13    ),
 14  inter as
 15    (select person_id, acc, trans, tyear, method,
 16       first_value(tyear) over (partition by person_id, acc, method order by trans) fv
 17       from test
 18    )
 19  select person_id, acc, max(fv) - min(fv) diff
 20  from inter
 21  group by person_id, acc
 22  having count(distinct method) > 1
 23  order by person_id, acc;

 PERSON_ID        ACC       DIFF
---------- ---------- ----------
         1         10          1
         2         15          2
         2         19          6
         3         21          2

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