【问题标题】:Joins tables in SQL with uneven rows without duplication在 SQL 中连接具有不均匀行且不重复的表
【发布时间】:2021-03-23 13:16:32
【问题描述】:

我在 SQL Server GRVGIV 中有两个表,其中包含这些列:

  • GRV:日期、产品 ID、产品名称、单位、接收数量
  • GIV:日期、产品 ID、产品名称、单位、数量

查询如下:

select 
    GRV.ProductID, GRV.ProductName, GRV.Unit, GRV.ReceivedQTY,
    GIV.ProductID, GIV.ProductName, GIV.Unit, GIV.Quantity
from 
    GRV
full outer join 
    GIV on GRV.ProductID = GIV.ProductID

这就是我得到的:

问题是红色字体的行实际上不在我的GIV 表中。我想要的只是表的实际数据应该按原样组合。右侧为GRV,左侧为GIV,没有偶数行表示null

有什么选择吗?我需要这个来创建一个库存分类帐水晶报表的原因,我可以在其中显示所有已收到和发出数量日期的交易,并最终生成期末余额。请在这方面帮助我。

【问题讨论】:

  • 一个简单的内连接而不是全连接?
  • P.Salmon 内部连接的问题是它会消除不匹配的值。正如我解释的那样,我需要所有数据,因为它是表格,因为很可能收到了一个产品但尚未发出,因此它应该显示在接收端。

标签: sql-server full-outer-join


【解决方案1】:

您的问题缺少明确的“预期结果”。

以下是一些可能对您有所帮助的选项。

样本数据

create table ItemIssued
(
  ProductId nvarchar(5),
  Quantity int
);
insert into ItemIssued (ProductId, Quantity) values
('P0001', 100),
('P0002',  50),
('P0004',   1);

create table ItemReceived
(
  ProductId nvarchar(5),
  Quantity int
);
insert into ItemReceived (ProductId, Quantity) values
('P0002',  55),
('P0003', 200);

解决方案 1

null

select i.ProductId as ProductId,
       i.Quantity as Quantity,
       r.ProductId as ProductId,
       r.Quantity as Quantity
from ItemIssued i
full join ItemReceived r
  on r.ProductId = i.ProductId;

解决方案 2

没有null

select coalesce(i.ProductId,'') as ProductId,
       coalesce(convert(nvarchar(5), i.Quantity),'') as Quantity,
       coalesce(r.ProductId,'') as ProductId,
       coalesce(convert(nvarchar(5), r.Quantity),'') as Quantity
from ItemIssued i
full join ItemReceived r
  on r.ProductId = i.ProductId;

解决方案 3

表格彼此相邻。

with ctei as
(
  select row_number() over(order by i.ProductId) as RowNum,
         i.ProductId,
         i.Quantity
  from ItemIssued i
),
cter as
(
  select row_number() over(order by r.ProductId) as RowNum,
         r.ProductId,
         r.Quantity
  from ItemReceived r
)
select ctei.ProductId,
       ctei.Quantity,
       cter.ProductId,
       cter.Quantity
from ctei
full join cter
  on cter.RowNum = ctei.RowNum;

解决方案 4

所有有数量的产品。

with cte as
(
  select i.ProductId
  from ItemIssued i
    union
  select r.ProductId
  from ItemReceived r
)
select c.ProductId,
       i.Quantity,
       r.Quantity
from cte c
left join ItemIssued i
  on i.ProductId = c.ProductId
left join ItemReceived r
  on r.ProductId = c.ProductId;

结果

与解决方案的顺序相同。

Fiddle 看看它的实际效果。

【讨论】:

  • Sander,首先非常感谢您以如此明确的方式解释解决方案。解决方案 3 是我的问题的实际解决方案。但是,尽管我在 Received 中有 2 条记录和在 Issue 中有 1 条记录,但我在 where 条件下使用它时,我只从两个表中获得了一条记录(我的表的记录不是由你创建的)。请您解释一下为什么会发生这种情况以及解决此问题需要进行哪些更改。
  • 我试图重现您的问题(更改了一些示例数据并添加了where 子句)并在this fiddle 中提供了解决方案。
猜你喜欢
  • 2012-09-26
  • 2015-06-30
  • 1970-01-01
  • 2021-11-25
  • 2011-05-14
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多