SQL - 仅查找具有不同付款条件的行

时间:2016-11-18 02:30:05

标签: sql sql-server

我有一个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

我想找到有多个送货地址的客户,但不是都有相同的付款条件。在此示例数据中,最后两行,同一客户(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          ║
╚═══════════════╩═════════════════════════════╩═══════════════════╝

1 个答案:

答案 0 :(得分: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;