首页 > 解决方案 > 解决 Vertica [Vertica][VJDBC](4160) 和 [Vertica][VJDBC](4680) 中的查询错误

问题描述

我在让 Vertica 查询正常工作方面遇到了一些问题。假设我有一个定义如下的关系:

CREATE TABLE KOMM (
   MANDT         VARCHAR(3),
   DOCNUM        VARCHAR(16),
   COUNTER       VARCHAR(3),
   NUM           VARCHAR(6),
   NAM           VARCHAR(30), 
   INNUM         VARCHAR(6),
   KOMMLEVEL     VARCHAR(2),  
   MSG           VARCHAR(1000),
   NUM_UNH       VARCHAR(6)
);

并插入一些示例值:

insert into KOMM values ('200','45320824','000','000003','START','000002','02','START OF MESSAGE');
insert into KOMM values ('200','45320824','000','000004','INTERMED','000003','03','EXAMPLEEXAMPLEEXAMPLE');
insert into KOMM values ('200','45320824','000','000005','ADV_01','000003','03','TESTADV1');
insert into KOMM values ('200','45320824','000','000011','END','000010','04','01234567');
...
insert into KOMM values ('200','45320824','000','000022','START','000002','02','CONTINUE START OF MESSAGE');
insert into KOMM values ('200','45320824','000','000023','INTERMED','000003','03','SECONDEXAMPLEEXAMPLEEXAMPLE');
insert into KOMM values ('200','45320824','000','000024','ADV_01','000003','03','SECONDTESTADV1');
insert into KOMM values ('200','45320824','000','000030','END','000010','04','01234567');

现在,我想用以下查询查询关系:

UPDATE KOMM E
SET NUM_UNH = (SELECT MAX(X.NUM)
                     FROM KOMM X
                    WHERE X.NAM IN ('START')
                      AND X.MANDT = E.MANDT
                      AND X.DOCNUM = E.DOCNUM
                      AND X.NUM <= E.NUM
                  )
FROM KOMM X
WHERE E.MANDT = X.MANDT AND E.DOCNUM = X.DOCNUM
;

但是,此查询会引发以下错误:

执行错误:[Vertica]VJDBC ERROR: Non-equalityrelated subquery expression is not supported

我认为这是因为 Vertica 不允许在子查询中进行 <=、>=、< 和 > 比较?有关子查询限制,请参见 Vertica 文档

所以我试图通过使用BETWEEN来解决它:

UPDATE KOMM E
SET NUM_UNH = (SELECT max(X.NUM)
                     FROM KOMM X
                    WHERE X.NAM IN ('START')
                      AND X.MANDT = E.MANDT
                      AND X.DOCNUM = E.DOCNUM
                      AND X.NUM BETWEEN '000000' AND (E.NUM)
                  )
from KOMM X
where E.MANDT = X.MANDT and E.DOCNUM = X.DOCNUM
;

这会导致相同的错误:

执行错误:[Vertica]VJDBC ERROR: Non-equalityrelated subquery expression is not supported

因此,我尝试忽略该条件并在执行以下查询后遇到了另一个问题:

UPDATE KOMM E
   SET NUM_UNH = (SELECT max(X.NUM)
                         FROM KOMM X
                        WHERE X.NAM IN ('START')
                          AND X.MANDT = E.MANDT
                          AND X.DOCNUM = E.DOCNUM
                      )
from KOMM X
where E.MANDT = X.MANDT and E.DOCNUM = X.DOCNUM
;

这导致了以下错误:

执行错误:[Vertica]VJDBC ERROR: Self joins in UPDATE statements are not allowed [Vertica][VJDBC]Detail: Target relationship "da592a51-45ee-4d3e-9983-e8a3e56fd852_2fd1ec98-bb71-4ad0-8d33-d751e209dcdd".KOMM 也出现在 FROM 列表中

我通过将"from KOMM X"替换为"from (select * from KOMM) X" 找到了解决此问题的“解决方法”。这个查询确实执行了,但并不如您所愿(如您所想)。目标是使用 NUM 值更新表,直到下一个更高的 NUM 值出现在表中,以便最终可以通过仅显示 NAM 为“START”的行来聚合表:

SELECT
M.MANDT, M.DOCNUM, M.NUM_UNH,
max(case
  when M.NAM = 'START' then substring(cast(M.MSG as varchar(99)),15,6)
end) as UNH_SEG,
max(case
    when M.NAM = 'END'
    then substring(cast(M.MSG as varchar(36)),4,33)
end) as PMSG
from KOMM M
group by M.MANDT, M.DOCNUM, NUM_UNH
;

第一行结果 第二行结果

不幸的是,我无法找到解决这些问题的方法,这就是为什么我希望你们能帮助我。提前感谢您的帮助和建议!

最好的问候,莫多

标签: sqlsubqueryvertica

解决方案


这是做你想做的吗?

UPDATE KOMM E
SET NUM_UNH = (SELECT MAX(CASE WHEN X.NUM <= E.NUM THEN X.NUM END)
               FROM KOMM X
               WHERE X.NAM IN ('START') AND
                     X.MANDT = E.MANDT AND
                     X.DOCNUM = E.DOCNUM
              );

我不熟悉 Vertica 更新的限制,但这是一个更简单的查询并且可能有效。

编辑:

这行得通吗?

UPDATE KOMM E
    SET NUM_UNH = X.NUM
FROM (SELECT MANDT, DOCNUM, MAX(CASE WHEN X.NUM <= E.NUM THEN X.NUM END) as NUM
      FROM KOMM X
      WHERE X.NAM IN ('START')  
      GROUP BY MANDT, DOCNUM                     
     ) X
WHERE X.MANDT= E.MANDT AND X.DOCNUM = E.DOCNUM;

推荐阅读