2016-11-18 44 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;