iSeries SQL: текущая дата не допускается при выборе записей для создания таблицы

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

  • внутренний подзапрос должен сравнивать дату действия второй таблицы с current_date (или CURDATE), а не с другим полем даты из основной таблицы
  • результаты используются для создания новой материализованной таблицы запроса

При этих предположениях SQL завершается ненормально, выдавая ошибку SQ20058, которую можно устранить двумя способами:

  • используя конкретную дату вместо current_date, что делает этот оператор бесполезным для моих целей
  • добавление

    disable query optimization
    

    к текущим настройкам в конце инструкции

    data initially deferred 
    refresh deferred        
    maintained by user
    

    что, в свою очередь, отключает оптимизацию запросов в операционной системе iSeries V7R1.

Чтобы решить эту проблему, я попытался создать представление со всеми записями, извлеченными внутренним подзапросом, затем выпустить оператор создания таблицы, присоединяющийся к представлению, чтобы избежать выполнения подзапроса, но снова материализованная таблица запроса не может адресовать представление, которое содержит ссылки на текущую дату.

Вы знаете, как я могу сравнить записи с текущей датой при создании таблиц? Что мне не хватает?

Спасибо

Пример: 1) данная таблица продаж определена как:

create table sales (
item_id decimal(3, 0),
sale_date date,         
sale_qty decimal(7, 2)
)

со следующим содержанием:

ITEM_ID  SALE_DATE   SALE_QTY 
    1    2016-01-10     10,00 
    1    2016-02-10     10,00
    1    2016-03-10     10,00 
    2    2016-01-10      5,00 
    2    2016-02-10      5,00 
    2    2016-03-10      5,00 

2) и представляет собой таблицу, определенную как:

create table depts (
item_id decimal(3, 0),
dept_from_date date,         
dept_id character(3)
)

со следующим содержанием:

ITEM_ID  DEPT_FROM_DATE  DEPT_ID
    1       2016-01-01     AAA  
    1       2016-03-01     BBB  
    2       2016-01-01     BBB  
    2       2016-02-01     CCC  
    2       2016-05-01     DDD  
    2       2016-12-01     EEE  

3) это ожидаемый результат:

select s.item_id, s.sale_date, s.sale_qty, d.dept_id
from sales s
left join depts d on d.item_id=s.item_id
and d.dept_from_date = (
select max(dept_from_date)
from depts x
where x.item_id = d.item_id and dept_from_date <= current_date)

  ITEM_ID  SALE_DATE   SALE_QTY   DEPT_ID
    1    2016-01-10     10,00     BBB  
    1    2016-02-10     10,00     BBB  
    1    2016-03-10     10,00     BBB  
    2    2016-01-10      5,00     DDD  
    2    2016-02-10      5,00     DDD  
    2    2016-03-10      5,00     DDD  

где идентификатор отдела сводится к самому последнему значению для целей бизнес-аналитики.

4) когда предыдущий оператор выбора встроен в оператор создания таблицы следующим образом:

create table sales2 as (
select s.item_id, s.sale_date, s.sale_qty, d.dept_id
from sales s
left join depts d on d.item_id=s.item_id
and d.dept_from_date = (
select max(dept_from_date)
from depts x
where x.item_id = d.item_id and dept_from_date <= current_date))
data initially deferred
refresh deferred       
maintained by user

он возвращает ошибку SQ20058.


person mlstoppa    schedule 05.09.2016    source источник
comment
Не могли бы вы дать нам пример SQL того, что вы пытаетесь сделать?   -  person Adrian Bannister    schedule 05.09.2016
comment
Я изменил вопрос, чтобы добавить полный пример. Спасибо.   -  person mlstoppa    schedule 05.09.2016
comment
Имейте в виду, что MQT - это не ПРОСМОТРЫ; По сути, они представляют собой ТАБЛИЦЫ, в которых хранятся данные, являющиеся результатом запроса. ПОДДЕРЖИВАЕТСЯ ПОЛЬЗОВАТЕЛЕМ или нет, основание данных на каком-либо изменяющемся значении практически сводит на нет цель кэширования данных.   -  person user2338816    schedule 06.09.2016
comment
Спасибо user2338816, я это знаю. Выбор между таблицей и представлением обусловлен временем отклика производительности, которое в нашем случае намного больше при использовании представления вместо таблицы из-за количества записей.   -  person mlstoppa    schedule 06.09.2016
comment
Тогда есть небольшая причина не использовать реальную таблицу, которую вы сначала заполняете, просто выполняя свой запрос из MQT. Дополнительные строки могут быть добавлены в / после полуночи только для добавления новых строк по дате. Я не понимаю, насколько лучше будет MQT.   -  person user2338816    schedule 06.09.2016
comment
Наверное, я вас не совсем понял. BI MQT обновляется каждую ночь для сбора данных примерно из 15 PF / таблиц (фактическая таблица?), Содержание которых может отличаться из-за некоторых отложенных процессов клиента. То есть мы не можем просто добавлять новые записи, потому что даже старые могут быть изменены.   -  person mlstoppa    schedule 06.09.2016
comment
Правильный способ пометить вопрос как решенный здесь, в Stack Overflow, - это принять ответ, который, по вашему мнению, лучше всего отвечает на вопрос за вас, как вы это сделали. Вам не нужно (и не следует) редактировать заголовок.   -  person Damien_The_Unbeliever    schedule 07.09.2016


Ответы (1)


Редактировать

Вы можете просто добавить параметр DISABLE QUERY OPTIMIZATION в конец вашего MQT. Из документации все, что он делает:

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

iSeries DB2 CREATE TABLE

Поэтому, если вы не хотите, чтобы система поддерживала MQT, а оптимизатор запросов использовал MQT для операторов выбора в исходных таблицах, вы можете просто указать параметр DISABLE QUERY OPTIMIZATION.

Оригинальный ответ

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

Видя, что MQT без параметра DISABLE QUERY OPTIMIZATION не позволяет использовать специальные регистры:

Подвыбор для материализованной таблицы запроса SALES2 недействителен для кода причины 8.

8 - относится к специальному регистру или глобальной переменной.

Нет правильного способа использования CURRENT_DATE в определении MQT. Поэтому я лично предлагаю вам просто создать представление на основе вашего оператора select.

При этом, вот метод взлома (или больше похожий на резню с бензопилой), который вы могли бы сделать:

Создайте таблицу, в которой будет храниться текущая дата:

CREATE TABLE cur_dat (cur_dat DATE)
INSERT INTO cur_dat VALUES(CURRENT DATE)

Затем создайте запись расписания заданий, которая будет обновлять эту таблицу каждую ночь в полночь:

QSYS/ADDJOBSCDE JOB(UPD_CURDAT)
                CMD(RUNSQL SQL('UPDATE cur_dat SET cur_dat = CURRENT DATE') COMMIT(*NONE))
                FRQ(*WEEKLY)
                SCDDATE(*NONE)
                SCDDAY(*ALL)
                SCDTIME('00:00:00')

Наконец, измените определение MQT на это:

CREATE TABLE sales2 AS (
SELECT s.item_id, s.sale_date, s.sale_qty, d.dept_id
FROM sales s
LEFT JOIN depts d ON d.item_id = s.item_id
  AND d.dept_from_date = (SELECT MAX(x.dept_from_date)
    FROM depts x, cur_dat y
    WHERE x.item_id = d.item_id
      AND x.dept_from_date <= y.cur_dat)
)
data initially deferred refresh immediate
person Adrian Bannister    schedule 05.09.2016
comment
Я попробую. Спасибо - person mlstoppa; 06.09.2016
comment
А как насчет отключения параметра оптимизации запроса? Можете ли вы помочь мне понять, почему наличие этого параметра позволяет использовать текущую дату в операторе SQL? Насколько это влияет на результаты? - person mlstoppa; 06.09.2016
comment
Я даже не рассматривал параметр отключения оптимизации запросов. Это был бы более изящный способ сделать это. Все, что делает параметр, - это не позволяет оптимизатору запросов учитывать этот MQT для операторов SELECT в продажах и отображает таблицы. См. Это: ibm.com/support/knowledgecenter/ssw_ibm_i_72/db2/ / а> - person Adrian Bannister; 06.09.2016
comment
Да, я видел такое же описание в справочнике по SQL, но оно мне мало что говорит. Я буду искать дополнительную информацию ... - person mlstoppa; 06.09.2016