SQL Server 使用左外连接的查询和通过返回重复项进行分组

9rnv2umw  于 2023-01-04  发布在  其他
关注(0)|答案(1)|浏览(222)

开始,我的数据库中有一个表,其中包含SalesForce信息。当我运行此示例查询时,它返回2行:

select * from SalesForce_INT_Account__c where ID_SAP_BAYER__c = '3783513'

当我在同一个表上运行下一个查询时,我获得了其中一行,这正是我所需要的:

SELECT MAX(ID_SAP_BAYER__c) FROM  SalesForce_INT_Account__c where ID_SAP_BAYER__c = '3783513' GROUP BY ID_SAP_BAYER__c

现在,我有了另一个表(PedidosEspecialesZarateCabeceras),它有一个字段(NroClienteDirecionEntrega),我可以将该字段与我在SalesForce表(ID_SAP_BAYER__c)中使用的字段进行匹配。
我需要做的是连接这两个表,以便从PedidosEspecialesZarateCabeceras中获取一行,并使用来自SalesForce表的附加字段,如果这些附加字段不可用,则它们应作为NULL值出现,因此我使用了LEFT OUTER JOIN。
问题是,因为我必须匹配NroClienteDirecionEntrega和ID_SAP_BAYER__c,并且salesforce表中有2行具有相同的ID_SAP_BAYER__c,所以我的查询返回来自PedidosEspecialesZarateCabeceras的2个重复行(它们都具有相同的NroPedido)。
以下是返回重复项的查询示例:

SELECT 
cab.CUIT AS CUIT, 
convert(nvarchar(4000), cab.NroPedido) AS NroPedido,

sales.BillingCity__c as Localidad,
sales.BillingState__c as IdProvincia,
sales.BillingState__c_Desc as Provincia,
sales.BillingStreet__c as Calle,
sales.Billing_Department__c as Distrito,
sales.Name as RazonSocial,

cab.NroCliente as ClienteId

FROM   PedidosEspecialesZarateCabeceras AS cab WITH (NOLOCK) 
             
     
                  LEFT OUTER JOIN

                         SalesForce_INT_Account__c AS sales WITH (NOLOCK) ON 
                         cab.NroClienteDireccionEntrega = sales.ID_SAP_BAYER__c 
                         and sales.ID_SAP_BAYER__c in
                                 ( SELECT MAX(ID_SAP_BAYER__c)

                                            FROM  SalesForce_INT_Account__c 
                                         GROUP BY ID_SAP_BAYER__c
                               )
                                 
WHERE cab.NroPedido ='5320'

即使连接具有MAX和Group By,这也会返回具有不同SalesForce信息的2个重复行(因为这2个SalesForce行具有相同的ID_SAP_BAYER__c),这应该是不可能的。

我需要的是查询中的左外连接只选择一个salesforce行,以防止像现在这样的重复。由于某种原因,带有group by的select max不起作用。
也许我应该尝试以不同的方式连接这些表,谁能给予我一些其他的想法,如何连接这两个表,只返回1行?无论从2中选择的SalesForce行是否正确,我只需要它选择其中之一。

wlzqhblo

wlzqhblo1#

您的IN子句实际上没有执行任何操作,因为...

SELECT MAX(ID_SAP_BAYER__c)
FROM  SalesForce_INT_Account__c 
GROUP BY ID_SAP_BAYER__c

...返回所有可能的IDSAP_BAYER__c值。(GROUP BY表示您希望为每个唯一的ID_SAP_BAYER__c返回一行,然后,由于MAX只对每个组中的一个唯一值进行操作,因此您只需返回该值。)
您可能希望更改查询,以便对您试图区分的两行之间实际上不同的值(可能是相关ID_SAP_BAYER__cMAX(ID))进行操作,此外,您可能希望将内部查询链接到外部查询。
您可能会执行以下操作:

...
LEFT OUTER JOIN
SalesForce_INT_Account__c sales
 ON cab.NroClienteDireccionEntrega = sales.ID_SAP_BAYER__c 
 and sales.ID in
 ( 
 SELECT MAX(ID)
 FROM SalesForce_INT_Account__c sales2
 WHERE sales2.ID_SAP_BAYER__c = cab.NroClienteDireccionEntrega
 )                               
WHERE cab.NroPedido ='5320'

通过使用sales.ID in ... SELECT MAX(ID) ...而不是sales.ID_SAP_BAYER__c in ... SELECT MAX(ID_SAP_BAYER__c) ...,可以确保只匹配ID_SAP_BAYER__c的两行之一。WHERE sales2.ID_SAP_BAYER__c = cab.NroClienteDireccionEntrega条件将内部查询链接到外部查询。
有多种方法可以完成上述操作,特别是当您不关心匹配哪些相关行时,您可以使用上述方法作为起点,并使其匹配您的首选样式。
另一种方法是将OUTER APPLYTOP 1一起使用。

SELECT 
 ...
FROM   PedidosEspecialesZarateCabeceras AS cab
OUTER APPLY(
 SELECT TOP 1 *
 FROM SalesForce_INT_Account__c s1
 WHERE cab.NroClienteDireccionEntrega = s1.ID_SAP_BAYER__c
) sales
WHERE cab.NroPedido ='5320'

如果没有ORDER BYTOP 1选择的匹配将是任意的,但我认为这正是您想要的(如果不是,您可以添加ORDER BY)。

相关问题