Oracle SQL сравнивает строки одной таблицы - PullRequest
0 голосов
/ 17 мая 2019

Таблица:

Date         shopId        amount
17-MAY-19      1             100
17-MAY-19      2             20
16-MAY-19      2             20
17-APR-19      1             50

Мне нужно найти эти записи той же таблицы в соответствии с требованиями:

По заданной дате, например, sysdate, найти запись с этой датой для каждого shopId(дата уникальна для каждого shopId), а также запись до 30 дней.

Сравните количество двух записей, чтобы увидеть, больше ли абсолютное значение% diff больше 5 (я использую 0,05 вместо% в приведенном ниже коде).

Если обе записи существуют, и% diff совпадает, запись должна быть в наборе результатов.

Сделайте это для всех shopId с и вернуть набор результатов.

Я могу извлечь записи и затем выполнить сравнение на внутренних языках, таких как JAVA и PHP, но мне интересно, лучше ли это делать с помощью SQL, с которым я не знаком.

select * 
from table t1 
inner join table t2 on t1.shopId = t2.shopId 
WHERE t1.ordertime = sysdate 
  and t2.ordertime = sysdate - 30 
  and abs( (t1.amount - t2.amount) / t2.amount > 0.05 ) 

Ожидаемый результат должен быть:

Table:
shopId     Date1     amount1      Date2     amount2
  1      17-MAY-19    100       17-APR-19      50

Пожалуйста, помогите, спасибо.

Ответы [ 2 ]

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

Вы должны использовать функцию trunc на sysdate, потому что sysdate всегда содержит текущую дату и время

with tab as(
  select to_date('17.05.2019','dd.mm.yyyy') as dat, 1 as shopid, 100 as amount from dual union all
  select to_date('17.05.2019','dd.mm.yyyy') as dat, 2 as shopid, 20 as amount from dual union all
  select to_date('16.05.2019','dd.mm.yyyy') as dat, 2 as shopid, 20 as amount from dual union all
  select to_date('17.04.2019','dd.mm.yyyy') as dat, 1 as shopid, 50 as amount from dual 

)

select * 
from tab t1 
join tab t2 on t1.shopid = t2.shopid 
WHERE t1.dat = trunc(sysdate)
  and t2.dat = trunc(sysdate - 30)
  and (t1.amount - t2.amount) / t2.amount > 0.05

Результат

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

Альтернативой объединениям может быть использование аналитической функции LAG, например ::10000

WITH your_table AS (SELECT to_date('17.05.2019','dd.mm.yyyy') dt, 1 shopid, 100 amount FROM dual UNION ALL
                    SELECT to_date('17.05.2019','dd.mm.yyyy') dt, 2 shopid, 20 amount FROM dual UNION ALL
                    SELECT to_date('16.05.2019','dd.mm.yyyy') dt, 2 shopid, 20 amount FROM dual UNION ALL
                    SELECT to_date('17.04.2019','dd.mm.yyyy') dt, 1 shopid, 50 amount FROM dual)
SELECT shopid,
       date1,
       amount1,
       date2,
       amount2
FROM   (SELECT shopid,
               dt date1,
               amount amount1,
               LAG(dt) OVER (PARTITION BY shopid ORDER BY dt) date2,
               LAG(amount) OVER (PARTITION BY shopid ORDER BY dt) amount2
        FROM   your_table
        WHERE  dt IN (TRUNC(SYSDATE), TRUNC(SYSDATE) - 30))
WHERE  amount1 > amount2 * 1.05;

    SHOPID DATE1          AMOUNT1 DATE2          AMOUNT2
---------- ----------- ---------- ----------- ----------
         1 17/05/2019         100 17/04/2019          50

Является ли это быстрее, чем версия соединения, решать вам и принять решение.

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