【问题标题】:SQL Server 2014 - How to Exclude records that don't have a certain value?SQL Server 2014 - 如何排除没有特定值的记录?
【发布时间】:2018-09-21 17:17:42
【问题描述】:

我有一个基于事务日期的派生临时表,如下所述:

-----------------------------------------------------------------------------------
|Account_No| Customer_Name   | Invoice_No  | Amount | Reason_Comment | Trans_Code |
-----------------------------------------------------------------------------------
|12345678  | John Doe        | A23782998   | 326.28 | Payment        |          2 |
-----------------------------------------------------------------------------------
|12345678  | John Doe        | A23782998   | 173.72 | Adjustment     |          3 |
-----------------------------------------------------------------------------------
|12345678  | John Doe        | A23782998   |   0.00 | Paid In Full   |  X         |
-----------------------------------------------------------------------------------
|23456789  | Bob Marley      | B58787934   | 500.00 | Payment        |          2 |
-----------------------------------------------------------------------------------
|23456789  | Bob Marley      | B58787934   |   0.00 | Paid In Full   |  X         |
-----------------------------------------------------------------------------------
|89034537  | Eric Clapton    | C78236428   |   0.00 | Paid In Full   |  X         |
-----------------------------------------------------------------------------------

您可能会注意到,Bob Markey 已付款,他的帐户显示为“已全额付款”。
埃里克克莱普顿很流畅。他较早付款,因此已显示为“已全额付款” John Doe 在这里需要一些“调整”形式的帮助,以便我们可以将他的帐户余额归零,从而“全额支付”

支付交易的 Trans_Code 为 2,Adjustment 3 并全额支付为 X。

我想排除在 TransCode 中仅具有“已全额支付”原因或 X 的交易。

我试过了:

SELECT * 
FROM #temp_table 
WHERE Account_No NOT IN 
     (SELECT Account_No FROM #temp_table 
      WHERE Reason_Comment = 'Paid In FUll'
        AND Reason_Comment <> 'PAYMENT' 
        AND Reason_Comment <> 'ADJUSTMENT')

也许,我应该使用NOT EXISTS

编辑:
这是我正在使用的表。因为我指定了日期范围,所以某些帐户只有一行,即“全额支付”行,因为调整或付款发生在指定日期范围之前。例如,下表中的最后一行 (Johnson Doe)。我想排除最后一行。

----------------------------------------------------------------------------------------------------------
|Account_No| Customer_Name   | Invoice_No  | Amount | Trans_No  |Reason_Comment | Trans_Date | Trans_Code|
----------------------------------------------------------------------------------------------------------
|12345678  | John Doe        | A23782998   | 326.28 |1234567    |Payment         | 2018-04-01 |         2|
----------------------------------------------------------------------------------------------------------
|12345678  | John Doe        | A23782998   | 687.58 |           |Amount Due      |            |         4|
----------------------------------------------------------------------------------------------------------
|23456789  | Jane Doe        | B12378299   | 123.56 |2345678    |Payment         | 2018-04-02 |         2|
----------------------------------------------------------------------------------------------------------
|23456789  | Jane Doe        | B12378299   | 336.44 |3456789    |Adjustment      | 2018-04-03 |         3|
----------------------------------------------------------------------------------------------------------
|23456789  | Jane Doe        | B12378299   |        |           |Paid In Full    |            |         X|
----------------------------------------------------------------------------------------------------------
|34567890  | Jonas Doe       | C34567998   | 500.55 |4567891    |Payment         | 2018-04-06 |         2|
----------------------------------------------------------------------------------------------------------
|34567890  | Jonas Doe       | C34567998   |        |           |Paid In Full    |            |         X|
----------------------------------------------------------------------------------------------------------
|45678912  | Johnson Doe     | D45678756   |        |           |Paid In Full    |            |         X|
----------------------------------------------------------------------------------------------------------

【问题讨论】:

  • 您希望得到什么样的结果?我觉得这个问题不清楚。
  • 这具有误导性,请澄清这一点,您要排除仅预付全款的交易吗?因此,您需要的输出是将 Eric Clapton 从记录中排除,因为他在一次付款中较早支付了全部金额,并且没有任何调整或分期付款!那是你要找的吗?请编辑您的帖子并使用给定示例的预期结果添加说明。

标签: sql sql-server not-exists


【解决方案1】:

你可以使用:

SELECT *
FROM tab t
WHERE NOT EXISTS (SELECT 1
                  FROM tab t2
                  WHERE t.Account_no = t2.Account_no
                    AND t.Invoice_no = t2.Invoice_no
                    AND (Reason_Comment IN ('Paid In FUll')
                         OR TransCode = 'X')
                  );

【讨论】:

    【解决方案2】:

    --你可以用不同的方式编写查询

    SELECT * 
    FROM #temptable 
    WHERE Reason_Comment != 'Paid In FUll'  AND trans_code != 'X'
    
    SELECT * 
    FROM #temptable 
    EXCEPT
    SELECT * 
    FROM #temptable 
    WHERE Reason_Comment = 'Paid In FUll'
    OR trans_code = 'X'
    

    【讨论】:

      【解决方案3】:

      正如我在评论中所说,您的帖子并不清楚您究竟需要排除什么,但从示例和您提供的查询中,我得出结论,您需要排除没有任何调整或分期付款计划(例如您的示例中的 Eric Clapton 之类的人),因为为什么您需要跟踪已经全额支付的付款(预付或提前支付),您不应该跟进那些已经分期付款或调整以确保您获得全额付款? 这就是我理解你的问题的方式,这对我来说是有意义的(也许)。

      如果这就是你要找的东西,那么你可以这样做:

      已更新(使用新提供的示例)

      SELECT
          Account_No, 
          Customer_Name, 
          Invoice_No, 
          Amount, 
          Trans_No,
          Reason_Comment, 
          Trans_Date,
          Trans_Code 
      FROM(
      SELECT
          Account_No, 
          Customer_Name, 
          Invoice_No, 
          Amount, 
          Trans_No,
          Reason_Comment, 
          Trans_Code, 
          CASE 
              WHEN 
                  COUNT(Account_No) OVER(PARTITION BY Account_No) = 1 AND Trans_Code = 'X'            
                  THEN NULL 
              ELSE  
                 COUNT(Account_No) OVER(PARTITION BY Account_No)
          END  AS NumberOfPayments, 
          Trans_Date 
      FROM Trans
      ) D
      WHERE 
          NumberOfPayments IS NOT NULL 
      AND (
              CAST(Trans_Date AS DATE) >= '2018-04-01'
          AND CAST(Trans_Date AS DATE) <= '2018-04-06'
          OR  Trans_Date IS NULL 
      )   
      

      这将返回:

      | Account_No | Customer_Name | Invoice_No | Amount | Trans_No | Reason_Comment |           Trans_Date | Trans_Code |
      |------------|---------------|------------|--------|----------|----------------|----------------------|------------|
      |   12345678 |      John Doe |  A23782998 | 326.28 |  1234567 |        Payment | 2018-04-01T00:00:00Z |         2  |
      |   12345678 |      John Doe |  A23782998 | 687.58 |   (null) |     Amount Due |               (null) |         4  |
      |   23456789 |      Jane Doe |  B12378299 | 123.56 |  2345678 |        Payment | 2018-04-02T00:00:00Z |         2  |
      |   23456789 |      Jane Doe |  B12378299 | 336.44 |  3456789 |     Adjustment | 2018-04-03T00:00:00Z |         3  |
      |   23456789 |      Jane Doe |  B12378299 | (null) |   (null) |   Paid In Full |               (null) |         X  |
      |   34567890 |     Jonas Doe |  C34567998 | 500.55 |  4567891 |        Payment | 2018-04-06T00:00:00Z |         2  |
      |   34567890 |     Jonas Doe |  C34567998 | (null) |   (null) |   Paid In Full |               (null) |         X  |
      

      NumberOfPayments 将根据发票编号计算每个帐号的付款。 您可以根据需要更改CASE 规则,还可以添加对分期付款有用的付款订单(付款1、付款2、付款3 ..等)。您需要做的就是添加这一行:

      ROW_NUMBER() OVER(PARTITION BY Invoice_No ORDER BY Trans_Code) AS PaymnetNumber
      

      这是Fiddle Demo

      【讨论】:

      • 我在查询中使用了这个确切的代码,但我收到一条错误消息“‘订单’附近的语法不正确。任何想法为什么?我的代码如下: SELECT * FROM (SELECT Account_No ,Customer_Name ,Invoice_No ,Amount ,Reason_Comment ,Trans_Code ,CASE WHEN Count(Account_No) OVER (PARTITION BY Invoice_No ORDER BY Invoice_No) = 1 AND Trans_Code = 'X' THEN NULL ELSE Count (Account_No) OVER (PARTITION BY Invoice_No ORDER BY Invoice_No) END AS NoOfPayments FROM #temp_table) D WHERE NoOfPayments 不为空
      • @user1777929 我已经更新了查询和演示。试试吧。它应该可以工作,甚至是前一个。
      • 是的。我之前通过删除 ORDER BY 部分进行了尝试。但是现在每个帐户我只得到 2 行。要么是调整并全额支付,要么是支付并全额支付。有很多账户都有付款、调整和全额支付。但这些账户没有显示付款和调整,也没有全额支付。它们仅显示为调整和全额支付。还有一个 Reason_Comment;这是“应付金额”。谢谢您的帮助。对此,我真的非常感激。 _我将编辑我的问题以显示我正在使用的修订表。
      • @user1777929 这是因为您错过了提及您刚刚添加到帖子中的信息,这使上述查询无效。告诉我,为什么有些客户在 Amount 和 Trans_Date 中有 NULL(或空)值?所以我更新了查询
      • @user1777929 我已经更新了查询以及 Fiddle 演示。检查出来。
      猜你喜欢
      • 2016-12-23
      • 1970-01-01
      • 2013-05-31
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      相关资源
      最近更新 更多