Sql server 通过匹配子项连接2个表
我试着有两个表,在这种情况下,它实际上是一个自联接中的一个表,由匹配的子级连接 让我先介绍一下这篇文章的目的,这样可以更好地理解我需要什么: 我正试图查找我刚收到的一份新订单,看看我们是否有过相同的订单,以便找出这是哪种包装箱类型。 因此,我需要匹配的订单包含相同的项目和相同的项目数量 查看下表,注意订单1300981与订单1303097具有相同的项目,如何编写此联接 请记住:我不希望结果包含任何与%100不匹配的匹配项 : : 预期结果Sql server 通过匹配子项连接2个表,sql-server,join,sql-server-2012,Sql Server,Join,Sql Server 2012,我试着有两个表,在这种情况下,它实际上是一个自联接中的一个表,由匹配的子级连接 让我先介绍一下这篇文章的目的,这样可以更好地理解我需要什么: 我正试图查找我刚收到的一份新订单,看看我们是否有过相同的订单,以便找出这是哪种包装箱类型。 因此,我需要匹配的订单包含相同的项目和相同的项目数量 查看下表,注意订单1300981与订单1303097具有相同的项目,如何编写此联接 请记住:我不希望结果包含任何与%100不匹配的匹配项 : : 预期结果 这可能是一种奇怪的方法,但是如果您将订单详细信息转换为x
这可能是一种奇怪的方法,但是如果您将订单详细信息转换为xml并将其与其他订单进行比较,则可以查找匹配项
WITH BoxOrders AS
(
SELECT om.[OrderId],
om.[BoxId],
(SELECT Item, Qty
FROM orderDetails od
WHERE od.[OrderId] = om.[OrderId]
ORDER BY Item
FOR XML PATH('')) Details
FROM orderMain om
WHERE BoxID IS NOT NULL
)
SELECT mo.OrderId, bo.BoxId
FROM BoxOrders bo
JOIN (
SELECT om.[OrderId],
om.[BoxId],
(SELECT Item, Qty
FROM orderDetails od
WHERE od.[OrderId] = om.[OrderId]
ORDER BY Item
FOR XML PATH('')) Details
FROM orderMain om
WHERE BoxID IS NULL
) mo ON bo.Details = mo.Details
这可能是一种奇怪的方法,但是如果您将订单详细信息转换为xml并将其与其他订单进行比较,则可以查找匹配项
WITH BoxOrders AS
(
SELECT om.[OrderId],
om.[BoxId],
(SELECT Item, Qty
FROM orderDetails od
WHERE od.[OrderId] = om.[OrderId]
ORDER BY Item
FOR XML PATH('')) Details
FROM orderMain om
WHERE BoxID IS NOT NULL
)
SELECT mo.OrderId, bo.BoxId
FROM BoxOrders bo
JOIN (
SELECT om.[OrderId],
om.[BoxId],
(SELECT Item, Qty
FROM orderDetails od
WHERE od.[OrderId] = om.[OrderId]
ORDER BY Item
FOR XML PATH('')) Details
FROM orderMain om
WHERE BoxID IS NULL
) mo ON bo.Details = mo.Details
这里有一种使用SQL和一些分析的不同方法
这将基于项目和数量以及订单号<其他订单号将订单详细信息连接到自身,并确保每个订单中的项目数匹配。因此,如果项目匹配、计数匹配和数量匹配,则订单具有相同的项目
这将返回两个订单,但很容易调整。使用CTE使计数具体化。很确定你不能用having来做这样的分析
我所做的一个主要假设是订单号是连续的,当你说看是否存在较旧的订单时,我应该只需要在评估之前的订单是否有相同的项目和数量时查看较早的订单号
我还假设100%匹配意味着:完全相同的项目。相同数量的物品。相同的项目数,订单1的项目数为3,订单2的项目数为3,项目和数量匹配为100%,但如果订单2有4个项目,订单1只有3个,则不匹配
with cte as (
SELECT distinct OD1.OrderID PriorOrder, od2.orderID newOrder, OM.BoxId,
count(OD1.Item) over (partition by OD1.OrderID) OD1Cnt,
count(OD2.Item) over (partition by OD2.OrderID) OD2cnt
FROM OrderDetails OD1
INNER JOIN orderDetails OD2
on OD1.item=OD2.item
and od1.qty = od2.qty
and OD1.OrderID < OD2.OrderID
LEFT JOIN ORderMain OM
on OM.OrderID = OD1.orderID)
Select PriorOrder, NewOrder, boxID from cte where od1cnt = od2cnt
这里有一种使用SQL和一些分析的不同方法
这将基于项目和数量以及订单号<其他订单号将订单详细信息连接到自身,并确保每个订单中的项目数匹配。因此,如果项目匹配、计数匹配和数量匹配,则订单具有相同的项目
这将返回两个订单,但很容易调整。使用CTE使计数具体化。很确定你不能用having来做这样的分析
我所做的一个主要假设是订单号是连续的,当你说看是否存在较旧的订单时,我应该只需要在评估之前的订单是否有相同的项目和数量时查看较早的订单号
我还假设100%匹配意味着:完全相同的项目。相同数量的物品。相同的项目数,订单1的项目数为3,订单2的项目数为3,项目和数量匹配为100%,但如果订单2有4个项目,订单1只有3个,则不匹配
with cte as (
SELECT distinct OD1.OrderID PriorOrder, od2.orderID newOrder, OM.BoxId,
count(OD1.Item) over (partition by OD1.OrderID) OD1Cnt,
count(OD2.Item) over (partition by OD2.OrderID) OD2cnt
FROM OrderDetails OD1
INNER JOIN orderDetails OD2
on OD1.item=OD2.item
and od1.qty = od2.qty
and OD1.OrderID < OD2.OrderID
LEFT JOIN ORderMain OM
on OM.OrderID = OD1.orderID)
Select PriorOrder, NewOrder, boxID from cte where od1cnt = od2cnt
您会提供要检查的OrderID吗?@SQLChao,绝对不会!整个想法是通过细节来找到匹配项。我同意多个结果,与普通联接相同。如果有多行匹配联接条件,则会给出多个结果。您是否提供要检查的OrderID?@SQLChao,绝对不是!整个想法是通过细节来找到匹配项。我同意多个结果,就像一个普通的连接会给出多个结果一样,如果有多行匹配连接条件,我喜欢它。非常干净/容易阅读。但是,如果BoxID为null,则即使存在先前的记录/匹配,它也不会返回。但根据要求,我认为这不会发生。我喜欢。非常干净/容易阅读。但是,如果BoxID为null,则即使存在先前的记录/匹配,它也不会返回。但基于需求,我认为这不会发生。
with cte as (
SELECT distinct OD1.OrderID PriorOrder, od2.orderID newOrder, OM.BoxId,
count(OD1.Item) over (partition by OD1.OrderID) OD1Cnt,
count(OD2.Item) over (partition by OD2.OrderID) OD2cnt
FROM OrderDetails OD1
INNER JOIN orderDetails OD2
on OD1.item=OD2.item
and od1.qty = od2.qty
and OD1.OrderID < OD2.OrderID
LEFT JOIN ORderMain OM
on OM.OrderID = OD1.orderID)
Select PriorOrder, NewOrder, boxID from cte where od1cnt = od2cnt