【问题标题】:How To Find Perfect Match With Multiple Rows Across Tables?如何找到表中多行的完美匹配?
【发布时间】:2019-11-24 17:37:17
【问题描述】:

我正在寻找一种方法来找出来自#Orders 的哪些行集合与#Pallets 最匹配。

在下面的示例中,@palletId = 1000 作为查询的输入,结果应该只能与 'Order2'(100% 匹配)'Order4'(75%匹配)。在这种情况下,我想要的结果是“Order2”。

输入 @palletId = 4000 应该 100% 与“Order4”匹配,并且没有其他匹配项。

DECLARE @paletId bigint = 1000

CREATE TABLE #Pallets ([PalletId] bigint, [Item] nvarchar(16), [Quantity] int)
CREATE TABLE #Orders ([OrderId] nvarchar(16), [Item] nvarchar(16), [Quantity] int)

INSERT INTO #Pallets ([PalletId], [Item], [Quantity]) VALUES 
(1000, 'item1', 10), 
(1000, 'item2', 10), 
(1000, 'item3', 10),
(4000, 'item1', 10), 
(4000, 'item2', 10), 
(4000, 'item3', 10),
(4000, 'item4', 10)

INSERT INTO #Orders ([OrderId], [Item], [Quantity]) VALUES 
('Order2', 'item1', 10), 
('Order2', 'item2', 10), 
('Order2', 'item3', 10),
('Order1', 'item1', 10),
('Order1', 'item2', 10),
('Order1', 'item3', 5),
('Order3', 'item2', 5),
('Order3', 'item3', 10),
('Order4', 'item1', 10), 
('Order4', 'item2', 10), 
('Order4', 'item3', 10),
('Order4', 'item4', 10),
('Order5', 'item1', 5), 
('Order5', 'item2', 5), 
('Order5', 'item3', 5),

DROP TABLE #ItemTable
DROP TABLE #LocationTable
DROP TABLE #BookingTable 
DROP TABLE #OrderTable

一直在尝试使用以下示例作为基础来解决它,但没有设法得到我想要的结果。

https://stackoverflow.com/a/27060384/2975371

https://stackoverflow.com/a/104001/2975371

提前致谢。

【问题讨论】:

  • 只是为了确保Order2 包含item1item2item3 - 这意味着它与#Pallets 表上的item1/2/3 的两个实例相关?您可能还想查看my answer 的类似问题。
  • @ZoharPeled 并且数量与正确的项目完全匹配。这主要是问题所在。因为 order5 也可以匹配,但数量仅为所需数量的 50%。

标签: sql sql-server tsql


【解决方案1】:

你可以试试

declare @cnt int
select @cnt = count(1) 
from #Pallets
where PalletId = @paletId 


select  top 1 OrderId 
from #Orders o
join #Pallets p on 
    o.Item = p.Item and 
    o.Quantity = p.Quantity and 
    p.PalletId = @paletId 
group by OrderId
order by abs(@cnt - count(PalletId))

我只是在这两者之间进行了区分,以确定哪一个“接近”100%。 abs(@cnt - count(PalletId)) 只会在 100% 匹配时返回零

【讨论】:

  • 我必须做一些测试,看看是否有它不起作用的情况。但乍一看,这个答案很有潜力。
【解决方案2】:

试试下面的查询:

declare @palletId int = 1000;
select OrderId,
       count(p.Item) * 1.0 / count(*) matchLevel
from #Orders o
left join (
    select Item, Quantity
    from #Pallets
    where palletId = @palletId
) p on o.Item = p.Item and o.Quantity = p.Quantity
group by OrderId

返回:

然后用top 1order by matchLevel desc 将其包装在查询中就足够了

【讨论】:

  • 这也很有效。但我接受了其他人的回答,因为它是第一个。
猜你喜欢
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 2018-07-30
  • 2015-06-30
相关资源
最近更新 更多