我有一个遗留系统,它有一个销售表和一个客户表,分别是CMS和CUST。我需要根据不同的标准查询发货地址。客户表将每个地址视为自己的客户。因此,如果我有一个帐单邮寄地址,那么一个送货地址,那些将是不同的CUSTNUM。 CMS表包含CUSTNUM和SHIPNUM列。如果销售订单使用帐单地址作为送货地址,则SHIPNUM = 0.如果这两个地址不同,则SHIPNUM =与CUSTNUM不同的客户编号。我正在尝试根据SHIPNUM的情况编写一个将CUST加入CMS的查询。 0或不。我的原始查询只使用了CUSTNUM,并忽略了SHIPNUM。我的新查询在语法上是正确的并且执行,但是对于旧查询,返回的行计数是2860对3590。旧的join语句只是注释掉的行:ON CMS.CUSTNUM = CUST.CUSTNUM。
from
KGI_LOTNOS as LOT
INNER JOIN CMS
ON LOT.ORDERNO = CMS.ORDERNO
JOIN CUST
ON CUST.CUSTNUM =
CASE
WHEN CMS.SHIPNUM > 0
THEN CMS.SHIPNUM
Else CMS.CUSTNUM
END
-- ON CMS.CUSTNUM = CUST.CUSTNUM
INNER JOIN COUNTRY as C
ON CUST.COUNTRY = C.COUNTRY
以下是CMS表中的示例;
CUSTNUM SHIPNUM ORDERNO
41863 77394 828509 <--Different billing and shipping address
43242 69291 776888 <--Different billing and shipping address
2356 0 765022 <--Same billing and shipping address
有关如何使这项工作的任何想法?
PS这是完整的原始查询。
select
CUST.CUSTNUM as Customer,
CMS.CUSTNUM,
CMS.SHIPNUM,
CUST.CTYPE,
CMS.ORDERNO,
CMS.ODR_DATE,
LTRIM(RTRIM(CUST.FIRSTNAME)) as First,
LTRIM(RTRIM(CUST.LASTNAME)) as Last,
LTRIM(RTRIM(CUST.COMPANY)) as Company,
LTRIM(RTRIM(CUST.PHONE)) as Phone,
LTRIM(RTRIM(CUST.EMAIL)) as Email,
LTRIM(RTRIM(CUST.ADDR)) as ADDR1,
LTRIM(RTRIM(CUST.ADDR2)) as ADDR2,
LTRIM(RTRIM(CUST.ADDR3)) as ADDR3,
LTRIM(RTRIM(CUST.CITY)) as City,
LTRIM(RTRIM(CUST.State)) as State,
LTRIM(RTRIM(CUST.ZIPCODE)) as Zip,
LTRIM(RTRIM(C.NAME)) as Country,
LOT.ITEMNO,
LOT.LOTNO,
COUNT(LOT.ITEMNO) as Quantity
from
KGI_LOTNOS as LOT
INNER JOIN CMS
ON LOT.ORDERNO = CMS.ORDERNO
LEFT JOIN CUST
ON CMS.CUSTNUM = CUST.CUSTNUM
INNER JOIN COUNTRY as C
ON CUST.COUNTRY = C.COUNTRY
where
(
CUST.CTYPE IN ('P','W','Z')
)
AND
(
LOT.LOTNO IN ('1000001','20001','300001')
)
GROUP BY
CMS.ORDERNO,
CUST.CUSTNUM,
CMS.CUSTNUM,
CMS.SHIPNUM,
CUST.CTYPE,
CUST.FIRSTNAME,
CMS.ODR_DATE,
CUST.LASTNAME,
CUST.COMPANY,
CUST.PHONE,
CUST.EMAIL,
CUST.ADDR,
CUST.ADDR2,
CUST.ADDR3,
LOT.ITEMNO,
CUST.CITY,
CUST.STATE,
CUST.ZIPCODE,
C.NAME,
LOT.LOTNO
ORDER BY
Customer,
CMS.ORDERNO,
LOT.ITEMNO,
LOT.LOTNO
答案 0 :(得分:1)
如果您使用INNER JOIN
,则有可能排除在另一个表中没有引用的原始数据。这可能是由表达式中的另外两个连接中的任何一个引起的 - 评论它们并再试一次。如果您仍然收到较少的记录,则应检查数据的一致性 - 一个表的值与另一个表中的值不对应。
顺便说一句,我不喜欢CASE
表达式中的JOIN
因为它看起来很难看。你对这个似乎也在做这个表达的表达方式有什么看法:
LEFT JOIN CUST
ON CUST.CUSTNUM = COALESCE(NULLIF(CMS.SHIPNUM, 0), CMS.CUSTNUM)
答案 1 :(得分:0)
使用更改的条件加入的记录越少,CMS.SHIPNUM
表中的某些CUSTNUM
值与CUST
不匹配。
要查找有问题的条目,请从INNER
更改为OUTER
加入并添加WHERE
条件,例如:
LEFT JOIN CUST
ON CUST.CUSTNUM = CASE WHEN CMS.SHIPNUM > 0 THEN CMS.SHIPNUM
ELSE CMS.CUSTNUM
END
WHERE CUST.CUSTNUM IS NULL
AND CMS.SHIPNUM > 0
修改:您必须将INNER JOIN
移至COUNTRY
才能看到与更新后的JOIN
无法匹配,因为它加入了来自客户表的字段,并确保在SHIPNUM
中有SELECT
字段。
答案 2 :(得分:0)
您可以使用这样的CTE。
WITH cte(ORDERNO,SHIPNUM)AS ( SELECT ORDERNUM,SHIPNUM = CASE 什么时候CMS.SHIPNUM&gt; 0
FROM CMS
答案 3 :(得分:0)
您的查询看起来正确但不确定为什么它不起作用,请尝试在发货时将joinCUST表保留两次,另一次在结算时保留,然后为每个客户列写下case语句。
select
LTRIM(RTRIM(case when CMS.SHIPNUM > 0 THEN CUST.FIRSTNAME else CUST_BILL.FIRSTNAME end )) as First,
from
KGI_LOTNOS as LOT
INNER JOIN CMS
ON LOT.ORDERNO = CMS.ORDERNO
left JOIN CUST CUST
ON CUST.CUSTNUM = CMS.SHIPNUM
left JOIN CUST CUST_BILL
ON CMS.CUSTNUM = CUST_BILL.CUSTNUM
INNER JOIN COUNTRY as C
ON CUST.COUNTRY = C.COUNTRY
如果它仍然输出较少的行,则其他错误