SQL Where子句不过滤掉“零”值

时间:2014-07-27 20:31:04

标签: sql sql-server filtering where-clause common-table-expression

我有两个名为Recovery and Installments的表。

Recovery ([pk] RID, emp_id, amount, duration, type]

Installments ([pk] ID, [fk] recovery_id, recovered_amount, date)

当员工获得贷款时,该信息存储在Recovery表中。然后从月薪中扣除这笔贷款。 (分期付款是[amount /duration])。 恢复后,恢复的分期付款的详细信息应存储在Installments表中。由于贷款可以分几次回收,因此恢复到分期付款的关系是1:M.

现在让我们说我只是想找出应该从薪水中扣除的所有恢复细节。我在这方面写过这个问题。在这里,我收取所有已付款分期付款的总和,然后从贷款金额中扣除,如果余额大于0,则计算分期付款。预期结果为Emp_DI | Installment

WITH Summary (RID, emp_id, amount, duration, installment) 

AS(

SELECT Recovery.RID, Recovery.emp_id, Recovery.amount, Recovery.duration,   SUM(Installment.recovered_installment) AS Installments
FROM Recovery LEFT OUTER JOIN
Installment ON Recovery.RID = Installment.recovery_id

WHERE Recovery.type = 'Loan'                       
GROUP BY Recovery.duration, Recovery.amount, Recovery.emp_id, Recovery.RID 
)  

SELECT emp_id, SUM(amount / duration) AS INS FROM Summary  
WHERE ((CASE WHEN installment != NULL THEN (amount-installment) 
                      ELSE(amount) END)> 0 )
GROUP BY emp_id 

这个查询运行良好,给出了一个例外的所需输出。即似乎WHERE子句中存在问题。

 WHERE ((CASE WHEN installment != NULL THEN (amount-installment) 
                          ELSE(amount) END)> 0 )

这不会按预期过滤掉余额为零的记录。我无法理解这个原因。你能帮我吗?非常感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

标准installment != NULL需要替换为installment is not null

All comparisons to NULL return FALSE.

对于你正在进行的具体比较,这个WHERE子句在眼睛上可能更容易:

WHERE (amount - COALESCE(installment,0)) > 0

答案 1 :(得分:1)

您需要is not null

 WHERE ((CASE WHEN installment IS NOT NULL THEN (amount-installment) 
               ELSE(amount) END)> 0 )

几乎与NULL的任何比较,包括= NULL<> NULL都会返回NULL。并且,NULL被视为错误。使用IS NULLIS NOT NULL

答案 2 :(得分:1)

 WHERE ( installment IS NOT NULL AND (amount-installment) > 0)
     OR ( installment IS NULL AND AMOUNT >0)

在Sql Server中,NULL是Unknown值,因此您无法将未知值与任何其他值进行比较。因此,在检查sql server中的空值时,请使用IS NULLIS NOT NULL

答案 3 :(得分:1)

我认为你打算把它放在有条款中吗?这有用吗?

WITH Summary as
 (SELECT Recovery.RID,
         Recovery.emp_id,
         Recovery.amount,
         Recovery.duration,
         SUM(Installment.recovered_installment) AS Installments
    FROM Recovery
    LEFT OUTER JOIN Installment
      ON Recovery.RID = Installment.recovery_id
   WHERE Recovery.type = 'Loan'
   GROUP BY Recovery.duration,
            Recovery.amount,
            Recovery.emp_id,
            Recovery.RID)
SELECT emp_id, SUM(amount / duration) AS INS
  FROM Summary
 GROUP BY emp_id
having sum (CASE WHEN installments is not NULL
                 THEN(amount - installments) ELSE(amount) END) > 0

正如其他人所指出的,&#34;不是空的&#34;也是说不等于null的正确方法。