2016-11-18 21 views
1

我有一个SQL查询可以从多个不同的表中查找客户及其付款条件。SQL - 仅查找具有不同付款条件的行

查询如下。

SELECT 
    c.CustomerCode, c.CustomerName, cst.PaymentTermCode 
FROM 
    CustomerShipTo cst 
JOIN 
    Customer c ON cst.CustomerCode = c.CustomerCode 
WHERE 
    cst.IsActive = 1 AND c.IsProspect = 0 AND c.IsActive = 1 

我想查找具有多个送货地址,但并不都具有相同付款条件的客户。在此示例数据中,最后2行,同一个客户(CUST-006002)有2个不同的送货地址和2个不同的支付代码,所以我只想选择这些行。

我尝试添加HAVING COUNT(CustomerCode) > 1子句到最后,但没有给出所需的输出,因为有时可能有多个送货地址的客户(在Customer E的情况下)但具有相同的付款期限。

╔═══════════════╦═════════════════════════════╦═══════════════════╗ 
║ Customer Code ║ Shipping Address   ║ Payment Term Code ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-016714 ║ Company A - Sample Address ║ NET30EOM   ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-017457 ║ Company B - Sample Address ║ NET30EOM   ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-016464 ║ Company C - Sample Address ║ COD    ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-017215 ║ Company D - Sample Address ║ COD    ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-006001 ║ Company E - Sample Address1 ║ NET30EOM   ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-006001 ║ Company E - Sample Address2 ║ NET30EOM   ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-006002 ║ Company F - Sample Address1 ║ COD    ║ 
╠═══════════════╬═════════════════════════════╬═══════════════════╣ 
║ CUST-006002 ║ Company F - Sample Address2 ║ NET30EOM   ║ 
╚═══════════════╩═════════════════════════════╩═══════════════════╝ 

回答

4

一种方法使用窗口函数。 SQL Server不支持COUNT(DISTINCT)作为窗口函数。但是,您可以比较最小值和最大值以查看是否存在多个值:

SELECT c.* 
FROM (SELECT c.CustomerCode, c.CustomerName, cst.ShippingAddress, 
      cst.PaymentTermCode, 
      MIN(cst.ShippingAddress) OVER (PARTITION BY c.CustomerCode) as minsa, 
      MAX(cst.ShippingAddress) OVER (PARTITION BY c.CustomerCode) as maxsa, 
      MIN(cst.PaymentTermCode) OVER (PARTITION BY c.CustomerCode) as minptc, 
      MAX(cst.PaymentTermCode) OVER (PARTITION BY c.CustomerCode) as maxptc 
     FROM CustomerShipTo cst JOIN 
      Customer c 
      ON cst.CustomerCode = c.CustomerCode 
     WHERE cst.IsActive = 1 AND c.IsProspect = 0 and c.IsActive = 1 
    ) c 
WHERE minptc <> maxptc AND minsa <> maxsa;