在DB2 SQL中,是否可以在SELECT语句中设置一个变量以多次使用。。?

在DB2 SQL中,是否可以在SELECT语句中设置一个变量以多次使用。。?,db2,ibm-midrange,db2-400,Db2,Ibm Midrange,Db2 400,在DB2SQL中,是否可以在SELECT语句中设置带有返回字段内容的变量,以便在同一SELECT语句中多次使用计算字段和条件 其目的是通过在开始时进行一次计算并在以后多次使用来缩减和简化代码…包括have、WHERE和ORDER by 老实说,我不确定这在任何版本的SQL中都是可能的,更不用说DB2了 这是在带有DB2SQLV6的IBMiSeries 8202上实现的,不幸的是,目前还不适合升级。这是一个非常旧和混乱的数据库,我无法控制。我必须定期在SQL中包含“清理函数” 为了澄清问题,请注意

在DB2SQL中,是否可以在
SELECT
语句中设置带有返回字段内容的变量,以便在同一
SELECT
语句中多次使用计算字段和条件

其目的是通过在开始时进行一次计算并在以后多次使用来缩减和简化代码…包括
have
WHERE
ORDER by

老实说,我不确定这在任何版本的SQL中都是可能的,更不用说DB2了

这是在带有DB2SQLV6的IBMiSeries 8202上实现的,不幸的是,目前还不适合升级。这是一个非常旧和混乱的数据库,我无法控制。我必须定期在SQL中包含“清理函数”

为了澄清问题,请注意以下伪代码。实际工作代码如下

DECLARE smnum INTEGER --Not sure if this is correct.
SELECT
-- This is where I'm not sure what to do.
SET CAST((CASE WHEN %smnum%='' THEN '0' ELSE %smnum% END) AS INTEGER) INTO smnum, 
%smnum% AS sm,
invdat, 
invno, 
daqty, 
dapric,
dacost,  
(dapric-dacost)*daqty AS profit
FROM 
saleshistory
WHERE 
%smNum% = 30
ORDER BY
%smnum%
下面是我实际使用的SQL。在2017年或2016年进行调整时,它可以返回>10K行,具体取决于销售人员。整个表有>22M行

CASE((CAST…
函数)的负载是我希望用变量替换的。这不是唯一的例子。如果我能使它工作,我还有许多其他查询可以从该技术中受益

SELECT

CAST((CASE WHEN TRIM(DASM#)='' THEN '0' ELSE TRIM(DASM#) END) AS INTEGER) AS DASM,
DAIDAT,
DAINV# AS DAINV,
DALIN# AS DALIN,
CAST(TRIM(DAITEM) AS INTEGER) AS DAITEM,
TRIM(DABSW) AS DABSW,
TRIM(DAPCLS) AS DAPCLS,
DAQTY,
DAPRIC,
DAICOS,
DADPAL,
(DAPRIC-DAICOS+DADPAL)*DAQTY AS PROFIT

FROM

VIPDTAB.DAILYV

WHERE

CAST((CASE WHEN TRIM(DASM#)='' THEN '0' ELSE TRIM(DASM#) END) AS INTEGER)=30 AND
TRIM(DABSW)='B' AND
DAIDAT BETWEEN (YEAR(CURDATE())*10000) AND (((YEAR(CURDATE())+1)*10000)-1) AND 
CAST(TRIM(DACOMP) AS INTEGER)=1

ORDER BY

CAST((CASE WHEN TRIM(DASM#)='' THEN '0' ELSE TRIM(DASM#) END) AS INTEGER),
DAIDAT,
DAINV#,
DALIN#

只需使用子查询或CTE。我无法理解您想要的实际逻辑,但结构如下所示:

select . . .
from (select d.*, 
             (CASE . . . END) as calc_field
      from VIPDTAB.DAILYV d
     ) d

不需要变量声明。

只需使用子查询或CTE。我无法理解您想要的实际逻辑,但结构如下所示:

select . . .
from (select d.*, 
             (CASE . . . END) as calc_field
      from VIPDTAB.DAILYV d
     ) d

不需要变量声明。

下面是Gordon建议的子查询的SQL外观:

SELECT

DASM,
DAIDAT,
DAINV# AS DAINV,
DALIN# AS DALIN,
CAST(DAITEM AS INTEGER) AS DAITEM,
TRIM(DABSW) AS DABSW,
TRIM(DAPCLS) AS DAPCLS,
DAQTY,
DAPRIC,
DAICOS,
DADPAL,
(DAPRIC-DAICOS+DADPAL)*DAQTY AS PROFIT

FROM

(SELECT 
   D.*, 
   CAST((CASE WHEN D.DASM#='' THEN '0' ELSE D.DASM# END) AS INTEGER) AS DASM
   FROM VIPDTAB.DAILYV D
) D

WHERE

DASM=30 AND
TRIM(DABSW)='B' AND
DAIDAT BETWEEN (YEAR(CURDATE())*10000) AND (((YEAR(CURDATE())+1)*10000)-1) AND 
CAST(DACOMP AS INTEGER)=1

ORDER BY

DASM,
DAIDAT,
DAINV#,
DALIN#
请注意,我删除了许多
trim()
函数,您可能会删除其余的。IBM解决Varchar与Char比较问题的方法是忽略尾随空格。因此
trim(anything)=''
anything='
相同。而且由于
强制转换('123'为整数)
=
123
,我也从cast函数中删除了修剪。此外,
trim(dabsw)='B'
dabsw='B'
相同,只要
'B'
dabsw
中的第一个字符。因此,如果您只关心尾随空格,甚至可以删除修剪

下面是一些基于注释的附加注释。上面的段落没有讨论自动修剪。固定长度字段将始终作为固定长度字段返回,尾随空格将保留。但是在比较和表达式中,尾随空格不重要,甚至是一个障碍,它们将被忽略。在尾随空格的表达式中与串联一样,尾随空格也很重要。另外,
trim()
会删除前导空格和尾随空格。如果使用
trim()
将固定长度字符字段读入
Varchar
,则
rtrim()
可能是更好的选择,因为它只删除后面的空格

另外,我没有检查你的字段以确保我得到了你需要的一切,我只是在子查询中使用了
*
。为了性能,最好只返回你需要的字段。因此,如果你用实际的字段列表替换
D.*
,你可以删除子查询from子句中的相关名称。但是,子查询它本身仍然需要一个关联子句


我的验证是使用IBM i v7.1完成的。

下面是Gordon建议的子查询的SQL外观:

SELECT

DASM,
DAIDAT,
DAINV# AS DAINV,
DALIN# AS DALIN,
CAST(DAITEM AS INTEGER) AS DAITEM,
TRIM(DABSW) AS DABSW,
TRIM(DAPCLS) AS DAPCLS,
DAQTY,
DAPRIC,
DAICOS,
DADPAL,
(DAPRIC-DAICOS+DADPAL)*DAQTY AS PROFIT

FROM

(SELECT 
   D.*, 
   CAST((CASE WHEN D.DASM#='' THEN '0' ELSE D.DASM# END) AS INTEGER) AS DASM
   FROM VIPDTAB.DAILYV D
) D

WHERE

DASM=30 AND
TRIM(DABSW)='B' AND
DAIDAT BETWEEN (YEAR(CURDATE())*10000) AND (((YEAR(CURDATE())+1)*10000)-1) AND 
CAST(DACOMP AS INTEGER)=1

ORDER BY

DASM,
DAIDAT,
DAINV#,
DALIN#
请注意,我删除了许多
trim()
函数,您可能会删除其余的。IBM解决Varchar与Char比较问题的方法是忽略尾随空格。因此
trim(anything)=''
anything='
相同。而且由于
强制转换('123'为整数)
=
123
,我也从cast函数中删除了修剪。此外,
trim(dabsw)='B'
dabsw='B'
相同,只要
'B'
dabsw
中的第一个字符。因此,如果您只关心尾随空格,甚至可以删除修剪

下面是一些基于注释的附加注释。上面的段落没有讨论自动修剪。固定长度字段将始终作为固定长度字段返回,尾随空格将保留。但是在比较和表达式中,尾随空格不重要,甚至是一个障碍,它们将被忽略。在尾随空格的表达式中与串联一样,尾随空格也很重要。另外,
trim()
会删除前导空格和尾随空格。如果使用
trim()
将固定长度字符字段读入
Varchar
,则
rtrim()
可能是更好的选择,因为它只删除后面的空格

另外,我没有检查你的字段以确保我得到了你需要的一切,我只是在子查询中使用了
*
。为了性能,最好只返回你需要的字段。因此,如果你用实际的字段列表替换
D.*
,你可以删除子查询from子句中的相关名称。但是,子查询它本身仍然需要一个关联子句


我的验证是使用IBM i v7.1完成的。

您可以将case语句封装在视图中。我甚至还有一个奇特的利润计算,供您按利润订购。现在您遇到的最大问题是视图中计算列的CCSID,但这是另一个问题

create or replace view VIPDTAB.DAILYVQ  as 

SELECT
CAST((CASE WHEN TRIM(DASM#)='' THEN '0' ELSE TRIM(DASM#) END) AS INTEGER) AS DASM,
DAIDAT,
DAINV# AS DAINV,
DALIN# AS DALIN,
CAST(TRIM(DAITEM) AS INTEGER) AS DAITEM,
TRIM(DABSW) AS DABSW,
TRIM(DAPCLS) AS DAPCLS,
DAQTY,
DAPRIC,
DAICOS,
DADPAL,
(DAPRIC-DAICOS+DADPAL)*DAQTY AS PROFIT

FROM

VIPDTAB.DAILYV
现在你可以

select dasm, count(*) from vipdtab.dailyvq where dasm = 0 group by dasm order by dasm


您可以将case语句封装在一个视图中。我甚至还有一个奇特的利润计算,供您按利润订购。现在您最大的问题是视图中计算列的CCSID,但这是另一个问题