При изменении параметра «NLS_CALENDAR» с григорианского на персидский, это не дает результата? - PullRequest
0 голосов
/ 12 мая 2019

У меня есть следующая таблица для расчета динамики запасов на складе.

create table TREND_WAREHOUSE
(
  id           NUMBER(30) not null,
  reg_date     NUMBER(30),
  org_id       NUMBER(30),
  goods_id     NUMBER(30),
  qty          NUMBER(30),
  reg_datetime TIMESTAMP(6)
)
insert into TREND_WAREHOUSE (id, reg_date, org_id, goods_id, qty, reg_datetime)
values (1, 13930527, 10, 1, 100, to_timestamp('18-08-2014 00:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'));
insert into TREND_WAREHOUSE (id, reg_date, org_id, goods_id, qty, reg_datetime)
values (2, 13930609, 10, 1, 20, to_timestamp('31-08-2014 14:03:44.689000', 'dd-mm-yyyy hh24:mi:ss.ff'));
insert into TREND_WAREHOUSE (id, reg_date, org_id, goods_id, qty, reg_datetime)
values (3, 13940902, 10, 1, -20, to_timestamp('23-11-2015 00:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'));
insert into TREND_WAREHOUSE (id, reg_date, org_id, goods_id, qty, reg_datetime)
values (4, 13940902, 10, 1, 100, to_timestamp('23-11-2015 00:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'));
insert into TREND_WAREHOUSE (id, reg_date, org_id, goods_id, qty, reg_datetime)
values (5, 13940902, 10, 1, 300, to_timestamp('23-11-2015 00:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'));
commit;

"reg_date" - это дата магазина в персидском календаре, которую я хочу использовать для расчета тренда инвентаря. вот мой запрос, чтобы вычислить его в григорианском календаре, и он успешно работает

WITH date_inventory_range AS
 (SELECT TRUNC(MIN(date_inventory), 'MONTH') AS first_date_inventory,
         ADD_MONTHS(TRUNC(MAX(date_inventory), 'MONTH'), 1) - 1 AS last_date_inventory

    FROM (SELECT W.ORG_ID,
                 W.GOODS_ID,
                 TO_DATE(TO_CHAR(CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE),
                                 'YYYYMMDD'/*,
                                 'NLS_CALENDAR=PERSIAN'*/),
                         'YYYYMMDD') date_inventory,
                 SUM(W.QTY) amount
            FROM TREND_WAREHOUSE W
           GROUP BY W.ORG_ID,
                    W.GOODS_ID,
                    CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE)
           ORDER BY 3)),
all_dates AS
 (SELECT first_date_inventory + LEVEL - 1 AS date_inventory
    FROM date_inventory_range
  CONNECT BY LEVEL <= 1 + last_date_inventory - first_date_inventory),
dense_data AS
 (SELECT s.org_id,
         s.goods_id,
         TRUNC(d.date_inventory, 'MONTH') AS mnth,
         NVL(SUM(s.amount) OVER(PARTITION BY s.org_id,
                  s.goods_id ORDER BY d.date_inventory),
             0) AS total_amount
    FROM all_dates d
    LEFT OUTER JOIN (SELECT W.ORG_ID,
                           W.GOODS_ID,
                           CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE) date_inventory,
                           SUM(W.QTY) amount
                      FROM TREND_WAREHOUSE W
                     WHERE W.Org_Id = 10
                       and W.Goods_Id = 1
                     GROUP BY W.ORG_ID,
                              W.GOODS_ID,
                              CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE)
                     ORDER BY 3) s PARTITION BY(s.org_id, s.goods_id)
      ON s.date_inventory = d.date_inventory)
SELECT org_id,
       goods_id,
       TO_CHAR(mnth, 'YYYY-MM') AS month,
       AVG(total_amount) AS month_avg
  FROM dense_data
 GROUP BY org_id, goods_id, mnth
 ORDER BY org_id, goods_id, mnth;

но когда я изменяю параметр "NLS_CALENDAR" на персидский, результат будет нулевым для всех месяцев.

WITH date_inventory_range AS
 (SELECT TRUNC(MIN(date_inventory), 'MONTH') AS first_date_inventory,
         ADD_MONTHS(TRUNC(MAX(date_inventory), 'MONTH'), 1) - 1 AS last_date_inventory

    FROM (SELECT W.ORG_ID,
                 W.GOODS_ID,
                 TO_DATE(TO_CHAR(CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE),
                                 'YYYYMMDD',
                                 'NLS_CALENDAR=PERSIAN'),
                         'YYYYMMDD') date_inventory,
                 SUM(W.QTY) amount
            FROM TREND_WAREHOUSE W
           GROUP BY W.ORG_ID,
                    W.GOODS_ID,
                    CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE)
           ORDER BY 3)),
all_dates AS
 (SELECT first_date_inventory + LEVEL - 1 AS date_inventory
    FROM date_inventory_range
  CONNECT BY LEVEL <= 1 + last_date_inventory - first_date_inventory),
dense_data AS
 (SELECT s.org_id,
         s.goods_id,
         TRUNC(d.date_inventory, 'MONTH') AS mnth,
         NVL(SUM(s.amount) OVER(PARTITION BY s.org_id,
                  s.goods_id ORDER BY d.date_inventory),
             0) AS total_amount
    FROM all_dates d
    LEFT OUTER JOIN (SELECT W.ORG_ID,
                           W.GOODS_ID,
                           CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE) date_inventory,
                           SUM(W.QTY) amount
                      FROM TREND_WAREHOUSE W
                     WHERE W.Org_Id = 10
                       and W.Goods_Id = 1
                     GROUP BY W.ORG_ID,
                              W.GOODS_ID,
                              CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE)
                     ORDER BY 3) s PARTITION BY(s.org_id, s.goods_id)
      ON s.date_inventory = d.date_inventory)
SELECT org_id,
       goods_id,
       TO_CHAR(mnth, 'YYYY-MM') AS month,
       AVG(total_amount) AS month_avg
  FROM dense_data
 GROUP BY org_id, goods_id, mnth
 ORDER BY org_id, goods_id, mnth;

спасибо за ваше руководство.

1 Ответ

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

Потому что вам нужно заменить CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE) на

TO_DATE(TO_CHAR(CAST(SUBSTR(W.REG_DATETIME, 1, 10) AS DATE),
                                 'YYYYMMDD',
                                 'NLS_CALENDAR=PERSIAN'),
                         'YYYYMMDD')

для каждых четырех вхождений, не только для SELECT-списка, но и в GROUP BY-списке.

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