Как запросить количество товара в день за последнюю неделю - PullRequest
1 голос
/ 07 мая 2019

Я пытаюсь написать запрос, который тянет инвентарь за каждый день, за последние 7 дней (неделю).Вот запрос:

select id, day, inventory
from tbl
where day >= DATEADD(day,-7, GETDATE())

Производит эту таблицу:

id      day         inventory
1223    2019-05-01  1
1223    2019-05-02  5
412345  2019-05-02  3
412345  2019-05-03  1
12      2019-05-02  8
1234    2019-05-01  467
1234    2019-05-02  493

Я не уверен, какой самый простой способ получить следующие результаты:

id      2019-05-01  2019-05-02  2019-05-03
1223    1           5
412345              3           1
12                  8
1234    467         493

1 Ответ

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

Поскольку в возвращении нет необходимости указывать конкретные имена столбцов, один из подходов к этому типу - PIVOT.
PIVOT может быть строгим при наличии статических сегментов, поэтому пример здесьиспользует динамический sql для перемещения 7-дневного окна.
У такого подхода есть некоторые реальные недостатки - динамический sql, скомпилированные объекты, грязный код и т. д., поэтому я не решаюсь на самом деле рекомендовать такой подход, но с использованием динамическогоsql позволяет предоставлять статические сегменты для PIVOT.
Ниже приведен пример с использованием предоставленной вами таблицы.

В этом примере будет суммироваться весь инвентарь за ID за каждый день за семидневный период, начинающийся с указанной даты.(По умолчанию за семь дней до сегодняшнего дня (исключая сегодняшний день)).

Чтобы разрешить вызов этого из SQL, в этом примере создаются некоторые объекты передачи данных и функция для их создания и возврата для 7-дневное окно.

Пример данных:

CREATE TABLE TBL (ID INTEGER, DAY DATE, INVENTORY INTEGER);
INSERT INTO TBL VALUES (1223, DATE '2019-05-01', 1);
INSERT INTO TBL VALUES (1223, DATE '2019-05-02', 5);
INSERT INTO TBL VALUES (412345, DATE '2019-05-02', 3);
INSERT INTO TBL VALUES (412345, DATE '2019-05-03', 1);
INSERT INTO TBL VALUES (12, DATE '2019-05-02', 8);
INSERT INTO TBL VALUES (1234, DATE '2019-05-01', 467);
INSERT INTO TBL VALUES (1234, DATE '2019-05-02', 493);
COMMIT;

Объекты:

CREATE OR REPLACE TYPE WEEK_INVENTORY IS OBJECT
(ID INTEGER, DAY_1 INTEGER, DAY_2 INTEGER, DAY_3 INTEGER, DAY_4 INTEGER, DAY_5 INTEGER, DAY_6 INTEGER, DAY_7 INTEGER);
/

CREATE OR REPLACE TYPE WEEK_INVENTORIES IS TABLE OF WEEK_INVENTORY;
/

Type created.
Type created.

И функция.Ввод DATE является началом семидневного окна.Функция выполняет динамический разворот, суммируя инвентарь для каждого ID, для каждого дня в семидневном окне.В этом примере все даты усекаются (я не уверен, потребуют ли это реальные данные).

CREATE OR REPLACE FUNCTION SEVEN_DAYS_OF_INVENTORY(P_START_DATE IN DATE DEFAULT SYSDATE - 7) RETURN WEEK_INVENTORIES
IS
V_BUCKETS_CLAUSE CHARACTER VARYING(256);
V_WEEK_INVENTORIES WEEK_INVENTORIES := WEEK_INVENTORIES();
BEGIN
    SELECT LISTAGG('DATE '''||TO_CHAR(P_START_DATE + (LEVEL - 1),'YYYY-MM-DD')||''' AS DAY_'||LEVEL,',')
        WITHIN GROUP(ORDER BY NULL)
        INTO V_BUCKETS_CLAUSE
    FROM  DUAL CONNECT BY LEVEL <= 7;

    EXECUTE IMMEDIATE UTL_LMS.FORMAT_MESSAGE('SELECT WEEK_INVENTORY(ID, DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7) FROM
(SELECT ID, INVENTORY, TRUNC(DAY) AS TRUNC_DAY FROM TBL)
PIVOT (SUM(INVENTORY) FOR TRUNC_DAY IN (%s))
ORDER BY ID ASC',V_BUCKETS_CLAUSE) BULK COLLECT INTO V_WEEK_INVENTORIES;
RETURN V_WEEK_INVENTORIES;
END;
/

Function created.

Затем проверьте его:

По умолчанию (сегодня 7 мая 2019 г., поэтому он начинается с 30 апреля 2019 г.):

SELECT * FROM TABLE(SEVEN_DAYS_OF_INVENTORY());

Результат:

       ID    DAY_1    DAY_2    DAY_3    DAY_4    DAY_5    DAY_6    DAY_7
_________ ________ ________ ________ ________ ________ ________ ________
       12                          8
     1223                 1        5
     1234               467      493
   412345                          3        1

Затем переместите его вперед на один день (1 мая 2019 г. - 7 мая 2019 г.):

SELECT * FROM TABLE(SEVEN_DAYS_OF_INVENTORY(SYSDATE - 6));

Результат:

       ID    DAY_1    DAY_2    DAY_3    DAY_4    DAY_5    DAY_6    DAY_7
_________ ________ ________ ________ ________ ________ ________ ________
       12                 8
     1223        1        5
     1234      467      493
   412345                 3        1

Или два дня (2 мая, 2019 - 8 мая 2019):

SELECT * FROM TABLE(SEVEN_DAYS_OF_INVENTORY(DATE '2019-05-02'));

Результат:

       ID    DAY_1    DAY_2    DAY_3    DAY_4    DAY_5    DAY_6    DAY_7
_________ ________ ________ ________ ________ ________ ________ ________
       12        8
     1223        5
     1234      493
   412345        3        1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...