【问题标题】:Only one record returned after union allunion all 后只返回一条记录
【发布时间】:2018-02-22 14:57:56
【问题描述】:

使用 SQL 接口进入 AS/400 (iSeries) DB2 数据库,但遇到并发出托盘信息可以存储在两个表中的位置,一个用于未分配库存(warpall),另一个用于分配股票(warpalq)。 如果适用,我需要从两个表中返回记录。

warpalq 只有少数几个与warpall 相关的字段 我需要来自warpall 的字段之一也用于加入另一个表,warpalq 中没有相关字段。

我使用union 在一个结果集中从两个表返回数据,然后加入其他表。

问题是,当在结果集上加入第三个表 (warcmdt) 时,它在 commpmfdsccd 字段中有空值 / 0,因为它在相应的表中没有相应的数据。

有没有办法可以将commpmfdsccd 拉回第2 行的结果集中? 交叉链接为pal#pm = pal#pq,因此存在相对链接。

运行下面的 SQL 会返回这个结果集。

select 
clntwf, commpm, fdsccd, clsqwf, pal#wf, dtcdpm, clsswf, srb#pm, descsc, 
cor#or  

from
(select substr(warpall.clntpm,1,2) as clntwf, pal#pm as pal#wf, commpm, 
substr(warpall.clsspm,1,2) as clsswf, warpall.clsqpm * 1 as clsqwf, srb#pm, 
dtcdpm, srd#pm 
from warpall

where 
locnpm <> 'ASSEMBLED PALLET'
and commpm <> 'ASSEMBLED PALLET'
and clsqpm <> 0
and clntPM <> 'D2'
and pal#pm = '1005609592'

union all

select substr(clntpq,1,2) as clntwf, pal#Pq as pal#wf, '0', 
substr(clsspq,1,2) as clsswf, clsqpq * 1 as clsqwf, '0', '0', '0' 
from warpalq

where 
clsqpq <> 0
and clntPQ <> 'D2'
and pal#pq = '1005609592'

) as t9

left outer join warcmdt as t3
on 
t3.clntcd = t9.clntwf  and t3.commcd = t9.commpm

left join
warclss as t4
on
t4.clsssc = t9.clsswf

left join
warohrh as t5
on
t5.clntor = t9.clntwf 
and t5.srn#or = t9.srd#pm

order by pal#wf asc

【问题讨论】:

  • 嗯,查询与您的第一个示例完全不同,并且具有不同的 where 子句和连接,因此如果没有样本数据,任何人都可能无法进行此评估。
  • 对不起,我只是简化了它- 重写一致性不好
  • 无需道歉。很可能是连接标准或 warpalq 表中的 where 子句存在问题。如果您放置您期望的记录样本,那么有人应该很容易发现问题。
  • 只是小费。在 union all 查询中,我添加了一个常量,这样我就可以知道行来自哪里 select 'mytablea' as t , a, b。 c from mytablea union all select 'mytableb' as t , a, b, c from tytableb
  • ...commpm 明确是 '0' 的常量 warpalq (作为 null 的替代?),它被用作 warcmdt 的连接条件的一部分.你确定那里有匹配的记录吗?正如 Jacob 所说,很可能由于加入标准,需要示例/所需的结果数据。

标签: sql db2 union db2-400


【解决方案1】:

您可以尝试像这样使用公用表表达式 (CTE):

with 
  pal (clntwf, pal#wf, commpm, clsswf, clsqwf, 
       srb#pm, dtcdpm, srd#pm) as (
    select
      substr(warpall.clntpm,1,2) as clntwf, 
      warpall.pal#pm as pal#wf, 
      warpall.commpm, 
      substr(warpall.clsspm,1,2) as clsswf, 
      warpall.clsqpm * 1 as clsqwf, 
      warpall.srb#pm, 
      warpall.dtcdpm, 
      warpall.srd#pm 
    from warpall
    where 
      warpall.locnpm <> 'ASSEMBLED PALLET'
      and warpall.commpm <> 'ASSEMBLED PALLET'
      and warpall.clsqpm <> 0
      and warpall.clntPM <> 'D2'
      and warpall.pal#pm = '1005609592'),

   alc (clntwf, pal#wf, commpm, clsswf, clsqwf, 
        srb#pm, dtcdpm, srd#pm) as (
     select 
       substr(warpalq.clntpq,1,2) as clntwf, 
       warpalq.pal#Pq as pal#wf, 
       pal.commpm, 
       substr(warpalq.clsspq,1,2) as clsswf, 
       warpalq.clsqpq * 1 as clsqwf, 
       '0', 
       '0', 
       pal.srd#pm 
     from warpalq
       join pal
         on waarpalq.pal#pq = pal.pal#wf
     where 
       warpalq.clsqpq <> 0
       and warpalq.clntPQ <> 'D2'
       and warpalq.pal#pq = '1005609592')

select 
  clntwf, commpm, fdsccd, clsqwf, pal#wf, dtcdpm, clsswf, srb#pm, descsc, cor#or  
from
  (select *
     from pal
   union all
   select *
     from alc
  ) as t9
  left outer join warcmdt as t3
    on t3.clntcd = t9.clntwf 
      and t3.commcd = t9.commpm
  left join warclss as t4
    on t4.clsssc = t9.clsswf
  left join warohrh as t5
    on t5.clntor = t9.clntwf 
      and t5.srn#or = t9.srd#pm
order by pal#wf asc

这使您可以在多个地方重复使用pal CTE,而无需重新定义它。这意味着您可以将其加入alc CTE 以获得commpm,该t9 稍后用于将t9warcmdt 一起加入。现在你不应该得到那个空值。我还将srd#pmwarpall 带入alc CTE,因为它用于t9warohrh 之间的连接。如果这不正确,您可以在alc CTE 中将pal.srd#pm 替换为'0'

【讨论】:

  • 效果很好!谢谢你。其中一个 warpalq 引用 (waarpalq) 中有一个错字,但由于它少于 6 个字符,我无法对其进行编辑。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 2023-03-27
  • 2016-05-22
  • 2018-09-13
相关资源
最近更新 更多