我很难想出一个查询来完成连接两个数据不匹配的表。
我有两个共享相同项目和序列号列的表,但保存了我需要加入一个表的不同信息。问题是表A中销售的商品与表B中销售的商品不匹配。我需要做的是将表B中的位置排列到表A中我们仍然携带的商品。希望这有助于说明:
Table A Table B
a.Item | a.Serial b.Item | b.Serial | b.Sold | b.Location | b.WHSerial
x45 36-0004 x45 36-0001 No Rack1Bin2 WH0044
x45 36-0005 x45 36-0002 No Rack1Bin2 WH0045
x45 36-0006 x45 36-0003 No Rack1Bin2 WH0046
x45 36-0007 x45 36-0004 No Rack1Bin3 WH0047
y11 55-0110 x45 36-0005 No Rack1Bin3 WH0048
y11 55-0111 x45 36-0006 Yes N/A WH0049
y11 55-0112 x45 36-0007 Yes N/A WH0050
y11 55-0109 No Rack33Bin5 WH0122
y11 55-0110 No Rack33Bin5 WH0123
y11 55-0111 No Rack33Bin5 WH0124
y11 55-0112 Yes N/A WH0125
期望输出
a.Item | a.Serial | b.Location | b.WHSerial
x45 36-0004 Rack1Bin3 WH0047
x45 36-0005 Rack1Bin3 WH0048
x45 36-0006 Rack1Bin2 WH0044
x45 36-0007 Rack1Bin2 WH0045
y11 55-0110 Rack33Bin5 WH0123
y11 55-0111 Rack33Bin5 WH0124
y11 55-0112 Rack33Bin5 WH0122
表A是主表,我需要将位置与每个序列号结合,但由于这种不匹配,我无法根据序列号加入。为了使其略微完成,表B中的某些项目的未售出序列号比表A中更多。表B中的任何额外未售出项目都可以忽略。
输出的逻辑是,如果表B中的匹配串行具有有效位置(不是N / A)那么它是好的,但如果没有,则有其他“未使用”的序列确实有效我要交换的地点。例如36-0006&表A中的36-0007未售出,但在表B中它们被出售并且具有无效的位置。如您所见,表B中的-0001到-0003在表A中没有匹配且具有有效位置。我想将这些位置用于-0006& -0007。从表B到表A的未使用的序列的分配可以是随机的,但它们需要保持唯一(如同,不要使用相同的未使用的串行两次)。
与b.Location一起,有一个相应的b.WHSerial需要在最终输出上。
答案 0 :(得分:1)
<强> DEMO 强>
首先计算未使用的位置并分配row_number。然后你会发现什么序列有一个匹配的位置,那些不是你的人也分配一个row_number。最后加入两者。所以未使用的位置只使用一次因为匹配rn。
WITH unusedLocation AS (
SELECT B.[Item], B.[Serial], B.[Sold], B.[Location], A.[Serial] as [code],
ROW_NUMBER() OVER (PARTITION BY B.[Item] ORDER BY B.[Location]) as rn
FROM [TableB] B
LEFT JOIN [TableA] A
ON A.[Item] = B.[Item]
AND A.[Serial] = B.[Serial]
WHERE B.Location <> 'N/A'
AND A.[Serial] IS NULL
), matchLocation AS (
SELECT A.[Item], A.[Serial], B.[Location],
ROW_NUMBER() OVER (PARTITION BY B.[Location], A.[item]
ORDER BY A.[Serial]) as rn
FROM [TableA] A
LEFT JOIN [TableB] B
ON A.[Item] = B.[Item]
AND A.[Serial] = B.[Serial]
AND B.Location <> 'N/A'
)
SELECT M.Item, M.Serial, COALESCE (M.Location, U.Location) as Location
FROM matchLocation M
LEFT JOIN unusedLocation U
ON M.Location IS NULL
AND M.Item = U.Item
AND M.rn = U.rn
ORDER BY M.Item, M.Serial;
<强>输出强>
第一张图片是您的输出,第二张是SELECT *
,因此您可以看到部分结果。这个版本你必须partition by item
所以重置为1。
答案 1 :(得分:0)
我们如何帮助您开始一些可以让您完成大部分工作的东西(命名N / A机架的逻辑我们不明白但是你去了:
Select A.*
,Case When B.Location Not Like 'N/A' Then B.Location
Else 'Rack1BinNA'
End As Location
From [Table A] A Left Join [Table B] B On A.Item = B.Item and A.Serial = B.Serial
Where A.Sold = 'No'
答案 2 :(得分:0)
使用项目代码和序列号的LEFT OUTER JOIN是否可以解决这个问题?例如;
LEFT OUTER JOIN TableB ON TableA.Item = TableB.Item
AND TableA.Serial = TableB.Serial
然后,您应该能够从两个表中选择所需的列。