Sql 基于部分信息合并发票和发货记录

Sql 基于部分信息合并发票和发货记录,sql,sql-server,Sql,Sql Server,我希望这只是我不知道要搜索的术语的一个例子,但我还没有找到解决这个问题的任何线索 我正在尝试连接两个表(发票和发货记录),其中一些信息丢失。特别是我通常用来加入的账户代码和订单号 考虑到每个订单在产品和数量的精确组合上都是相当独特的,我希望通过比较订单的组成来加入表格 例如,根据以下数据,应该可以确定order\u refA1的装运记录与invoice\u num500相关,因为它包含数量完全相同的相同产品 shipping_id | order_ref | product | quanti

我希望这只是我不知道要搜索的术语的一个例子,但我还没有找到解决这个问题的任何线索

我正在尝试连接两个表(发票和发货记录),其中一些信息丢失。特别是我通常用来加入的账户代码和订单号

考虑到每个订单在产品和数量的精确组合上都是相当独特的,我希望通过比较订单的组成来加入表格

例如,根据以下数据,应该可以确定
order\u ref
A1的装运记录与
invoice\u num
500相关,因为它包含数量完全相同的相同产品

  shipping_id | order_ref | product | quantity 
 -------------|-----------|---------|---------- 
          100 | A1        | Apple   |        1 
          101 | A1        | Banana  |        1 
          102 | A1        | Carrot  |        2 


  invoice_num | line_num | product | quantity 
 -------------|----------|---------|---------- 
          500 |        1 | Apple   |        1 
          500 |        2 | Banana  |        1 
          500 |        3 | Carrot  |        2 
          501 |        1 | Apple   |       10 
          501 |        2 | Banana  |        1 
          501 |        3 | Carrot  |        2 

改为按产品和数量加入:

select table_a.*, table_b.* 
from table_a
join table_b on table_a.product = table_b.product
and  table_a.quantity = table_b.quantity

您可以为每个组创建一个键,并使用该键联接

在您的示例中,
Apple\u 1\u Banana\u 1\u Carrot\u 2\

DECLARE @shipping TABLE  (shipping_id INT, order_ref VARCHAR(10), product VARCHAR(10), quantity INT)
INSERT INTO @shipping VALUES
(100 , 'A1', 'Apple', 1), 
(101 , 'A1', 'Banana', 1), 
(102 , 'A1', 'Carrot', 2) 

DECLARE @invoice TABLE  (invoice_num INT, line_num INT, product VARCHAR(10), quantity INT)
INSERT INTO @invoice VALUES
(500, 1 ,'Apple',  1 ),
(500, 2 ,'Banana',  1 ),
(500, 3 ,'Carrot',  2 ),
(501, 1 ,'Apple', 10 ),
(501, 2 ,'Banana',  1 ),
(501, 3 ,'Carrot',  2 )

SELECT * FROM (
    SELECT * FROM @shipping s
        CROSS APPLY(SELECT product + '_' + CAST(quantity AS varchar(10)) + '_'  
            FROM @shipping s2 WHERE s.order_ref = s2.order_ref 
            ORDER BY product , quantity FOR XML PATH('')) X(group_key)
) A
INNER JOIN 
    (SELECT * FROM @invoice i
        CROSS APPLY(SELECT product + '_' + CAST(quantity AS varchar(10)) + '_'  
            FROM @invoice i2 WHERE i.invoice_num = i2.invoice_num 
            ORDER BY product , quantity FOR XML PATH('')) X(group_key) 
)B ON A.group_key = B.group_key 
    AND A.product = B.product
    AND A.quantity = B.quantity
结果:

shipping_id order_ref  product    quantity    line_num             invoice_num line_num    product    quantity   
----------- ---------- ---------- ----------- -------------------- ----------- ----------- ---------- -----------
100         A1         Apple      1           1                    500         1           Apple      1          
101         A1         Banana     1           2                    500         2           Banana     1          
102         A1         Carrot     2           3                    500         3           Carrot     2          

我认为没有一种合适的SQL方式可以这样连接,但您可以执行以下操作:

SELECT order_ref, STRING_AGG(product + quantity, '_') as product_list
FROM
(SELECT * FROM shipping_records ORDER BY product) AS inner_shipping_records
GROUP BY
order_ref
然后

SELECT invoice_num, STRING_AGG(product + quantity, '_') as product_list
FROM
(SELECT * FROM invoices ORDER BY product) AS inner_invoices
GROUP BY
invoice_num
然后在产品列表字段中加入:

SELECT * FROM
( SELECT order_ref, STRING_AGG(.... ) as a_products JOIN
( SELECT invoice_num, STRING_AGG(.... ) as a_shipping_records
ON a_products.product_list = a_shipping_records.product_list

我还没有在SQLServer上测试过这个,但它应该可以工作。我不认为这会很快,但你可以设计出某种功能索引或视图来加快速度。

用你正在使用的数据库标记你的问题。谢谢Tim,但我需要加入到订单的完整组成中,这样会给我太多的误报。看来塞尔坎的答案也有同样的作用,所以我很欣赏这里的逻辑。我听到了你关于速度的说法,但这只是为了解决剩下的5%的数据质量差的订单,所以速度不是必需的。没问题。不过,我的解决方案并没有提供完全相同的输出。我的目标只是一份订单参考与发票数量的列表,而不是与该订单相关的所有产品。很高兴你找到了解决办法。