感谢您提前获得任何反馈。
我对这个SQL脚本有以下难题。我正在从db2服务器读取,该脚本由三个表组成,但其中两个表给我一个问题。
我有表1,这个表是位置表。该表包含两个关键列PL_COUNT
和LOC_SYSID
。 PL_COUNT
告诉许多每个位置适合多少个plts。
表2,此表是库存表,该表仅包含LOC_SYSID
个字段,但LOC_SYSID
列是查找该位置中有多少个plts的关键。为了找到位置中有多少个plts,我做了一个总和来确定每个位置使用LOC_SYSID
加入多少个plts。这很完美,但是当库存表的总和返回的记录多于PL_COUNT
可以容纳的记录时。总和不正确我想强制脚本使用位置表中的PL_COUNT
值。
我尝试了几件事,但没有运气。方法是使用案例,当库存表的总和>比位置表中的PL_CCOUNT
,我会强制使用PL_COUNT
。但是,案例方法不起作用,我每次都会遇到错误。在这一点上,我没有想法,也不知道这种方法是否可行。
再次感谢任何反馈
LOCATIONS TABLE 1
|LOC_SYSID |PL_COUNT|whsesysid|
|10001 |2 |1 |
|10002 |2 |1 |
|10003 |2 |1 |
|10004 |2 |2 |
|10005 |1 |2 |
|10006 |1 |2 |
INVENTORY TABLE 2
PLT_SYSID |LOC_SYSID|whsesysid|
|1 |10001 |1 |
|2 |10001 |1 |
|3 |10001 |1 |
|4 |10002 |1 |
|5 |10002 |1 |
|6 |10002 |1 |
|7 |10002 |1 |
|8 |10003 |1 |
|9 |10003 |1 |
|10 |10003 |1 |
|11 |10004 |2 |
|12 |10005 |2 |
|13 |10006 |2 |
|14 |10006 |2 |
|15 |10006 |2 |
|16 |10006 |2 |
SQL OUTPUT
whseSysId |whsename|availableFootprints |usedFootprints
|1 |10001 |8 |10 In this result it should be 8, but since ls1 has 3, ls2 has 4, and ls3 has 3
|2 |10002 |4 |6 Same issue, this should be 4.
SELECT
wh.WHSE_SYSID AS whseSysId,
(SELECT
SUM(loc.PL_COUNT)
FROM ROOM rm
INNER JOIN LOCATIONS loc
ON rm.ROOM_SYSID = loc.ROOM_SYSID
WHERE loc.PL_COUNT > 0
AND rm.WHSE_SYSID = :whseSysId)
AS availableFootprints,
SUM(
BIGINT(
ROUND((SELECT
SUM(CASE
WHEN st.INVTRY_PALLET_STACK_SYSID IS NULL THEN 1
ELSE 0.5
END)
FROM ROOM rm
INNER JOIN LOCATIONS loc
ON rm.ROOM_SYSID =
loc.ROOM_SYSID
INNER JOIN INVTRY_PALLET_DTL p
ON loc.LOC_SYSID =
p.LOC_SYSID
LEFT JOIN INVTRY_PALLET_STACK st
ON p.WHSE_SYSID = st.WHSE_SYSID
AND (p.INB_LPN =
st.MASTER_INB_LPN
OR p.INB_LPN = st.INB_LPN)
WHERE rm.WHSE_SYSID = :whseSysId), 0
)
)
) AS usedFootprints
FROM WHSE wh
WHERE wh.WHSE_SYSID = :whseSysId
GROUP BY wh.WHSE_SYSID,
wh.WHSE_NAME;
答案 0 :(得分:0)
我建议“首先考虑加入”(即通过连接寻找包含数据的方式,而不是在select子句中使用子查询)。
我就是这样做的。利用现有的子查询但将它们推送到FROM子句中,为此我们需要一种连接方式,因此它们现在都是GROUP BY rm.WHSE_SYSID,以便结果可以连接到wh.WHSE_SYSID。请注意,因此您不需要在绑定变量中使用这么多where子句:whseSysId(优化器会为您排序)。
将所有数据源移动到FROM子句后,只需使用列别名作为所需的case表达式。更简单。 (也可能更快。)
SELECT
wh.WHSE_SYSID
, wh.WHSE_NAME
, loc.availableFootprints
, rm.usedFootprints
, case
when rm.usedFootprints > loc.availableFootprints then loc.availableFootprints
else rm.usedFootprints
end AS Whatever
FROM WHSE wh
LEFT JOIN (
SELECT
rm.WHSE
, SUM(loc.PL_COUNT) AS availableFootprints
FROM ROOM rm
INNER JOIN LOCATIONS loc ON rm.ROOM_SYSID = loc.ROOM_SYSID
WHERE loc.PL_COUNT > 0
GROUP BY rm.WHSE_SYSID
) loc ON wh.WHSE_SYSID = loc.WHSE_SYSID
LEFT JOIN (
SELECT
rm.WHSE_SYSID
, SUM(CASE
WHEN st.INVTRY_PALLET_STACK_SYSID IS NULL
THEN 1
ELSE 0.5 END) AS usedFootprints
FROM ROOM rm
INNER JOIN LOCATIONS loc ON rm.ROOM_SYSID = loc.ROOM_SYSID
INNER JOIN INVTRY_PALLET_DTL p ON loc.LOC_SYSID = p.LOC_SYSID
LEFT JOIN INVTRY_PALLET_STACK st ON p.WHSE_SYSID = st.WHSE_SYSID
AND (p.INB_LPN = st.MASTER_INB_LPN OR p.INB_LPN = st.INB_LPN)
GROUP BY rm.WHSE_SYSID
) rm ON wh.WHSE_SYSID = rm.WHSE_SYSID
WHERE wh.WHSE_SYSID = :whseSysId
;
我使用了LEFT JOINS,因为我不知道你的数据。如果任何子查询加入WHSE时可能会导致NULL,因为没有连接的行,那么您可能必须将COALESCE()引入case表达式,仅作为示例:< / p>
, coalesce(case
when rm.usedFootprints > loc.availableFootprints then loc.availableFootprints
else rm.usedFootprints
end,0) AS Whatever