iSeries SQL:选择记录以创建 table 时不允许使用当前日期

iSeries SQL: current date not allowed when selecting records to create a table

我需要创建一个具体化查询 table,其中的记录具有通过子查询在第二个 table 上检索到的属性,以便获取该属性的最新值。 这个问题与此处讨论的问题非常相似:Retrieving the last record in each group 除了以下内容:

在这些假设下,SQL 异常结束并给出 SQ20058 错误,可以通过两种方式消除:

为了解决这个问题,我尝试创建一个视图,其中包含内部子查询提取的所有记录,然后发出一个 create table 语句加入视图,以避免执行子查询,但再次具体化查询 table 无法找到包含对当前日期的引用的视图。

您知道如何在创建 table 时将记录与当前日期进行比较吗? 我错过了什么?

谢谢

示例: 1) 给定销售额 table 定义为:

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) 和部门 table 定义为:

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  

出于 BI 目的,部门 ID 被扁平化为其最新值

4) 当前面的 select 语句嵌入到创建 table 语句中时,如下所示:

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

它returns SQ20058 错误。

编辑

您只需将“DISABLE QUERY OPTIMIZATION”参数添加到 MQT 的末尾即可。从文档来看,它所做的是:

Specifies that the materialized query table cannot be used for query optimization. The table can still be queried directly.

iSeries DB2 CREATE TABLE

因此,除非您希望系统维护 MQT 并且查询优化器将 MQT 用于原始 table 上的 select 语句,否则您可以只指定 DISABLE QUERY OPTIMIZATION 参数。

原答案

在“数据最初延迟立即刷新”参数的情况下,我把它留在这里。指定用于系统维护的 MQT。

看到没有“DISABLE QUERY OPTIMIZATION”参数的 MQT 不允许您使用特殊寄存器:

Subselect for materialized query table SALES2 not valid for reason code 8.

8 -- Refers to a special register or global variable.

在 MQT 的定义中没有使用 CURRENT_DATE 的任何正确方法。因此,我个人建议您最好根据 select 语句创建一个视图。

话虽这么说,这里有一个黑客(或更像是电锯大屠杀)方法,你可以这样做:

创建一个 table 来存储当前日期:

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

然后创建一个作业计划条目,每晚 table 午夜更新此条目:

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