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



在db2 sql中,是否可以在 SELECT语句中使用返回字段的内容的 SET在同一 SELECT语句中使用返回字段的内容进行多次用于计算的字段和标准?

目的是通过在开始时进行一次计算,然后在...(包括HAVINGWHEREORDER BY

说实话,我不确定在任何版本的SQL中都可以,更不用说DB2。

这是在带有DB2 SQL V6的IBM iSeries 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

不需要可变声明。

这是您的SQL所建议的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 vs. char比较的方式是忽略落后空白。因此,trim(anything) = ''anything = ''相同。而且由于cast(' 123 ' as integer) = 123,因此我也从铸件功能中删除了装饰。另外,只要'B'dabsw中的第一个字符,trim(dabsw) = 'B'dabsw = 'B'相同。因此,如果您所关注的只是落后的空白,您甚至可以删除该装饰。

这是一些基于评论的其他注释。上面的段落不是在谈论自动三。固定长度字段将始终作为固定长度字段返回,尾随空白将保留。但是,在比较和表达中,落后的空白不重要,甚至是障碍,它们被忽略了。在尾随的毛坯很重要的表达式中,例如串联,尾随的空白不被忽略。另一件事是,trim()删除了前导和尾随的空白。如果您使用trim()将固定长度字段读取到Varchar中,则rtrim()可能是更好的选择,因为它只会删除尾随的空白。

另外,我没有通过您的领域来确保我得到了您所需的一切,我只是在子问题中使用了*。对于性能,最好只返回所需的字段。因此,如果将D.*替换为实际字段列表,则可以在子查询的"来自子句"中删除相关名称。但是,子查询本身仍然需要一个相关条款。

我的验证是使用IBM IV7.1。

进行的

您可以在视图中封装案例语句。我什至在那里有奇特的利润来供您订购利润。现在,您最大的问题是计算列的视图上的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

select * from vipdtab.dailyvq order by profit desc

相关内容

  • 没有找到相关文章

最新更新