postgresql:附加的WHERE子句隐藏行

时间:2017-03-17 12:12:16

标签: sql postgresql where

我的SQL请求加入了2个表,结果是付款金额,按付款方式分组。付款方式显示在payment_history表格中: BlueMedia Transferuj,BankPayment ChangeSum 。此外,payment_history.payment_method列可以包含空字符串或NULL - 在这种情况下,我想将其检索为“其他”字样。值。

SQL查询是:

SELECT 
    CASE
        WHEN COALESCE(payment_history.payment_method, '') = '' THEN 'other'
        ELSE payment_history.payment_method
    END as payment_method, 
    CASE
        WHEN SUM(paid_balance) IS NULL THEN 0.00
        ELSE SUM(paid_balance)
    END as paid_balance, 
    CASE
        WHEN SUM(sum_without_commission) IS NULL THEN 0.00
        ELSE SUM(sum_without_commission)
    END as sum_without_commission                   
FROM 
    payment_history 
    LEFT JOIN 
    participants_list ON payment_history.registration_id = participants_list.registration_id 
WHERE 
    payment_history.client_id = 258 AND
    participants_list.deleted = 0 AND
    participants_list.is_reserved = 0
GROUP BY payment_history.payment_method

结果(没有付款方式 Transferuj 的记录,它没有问题,导致id = 258的当前客户缺席

enter image description here

other表示该记录存在于payment_history中,其中payment_methodNULL或空字符串。

不希望检索记录,其中付款方式为ChangeSum。所以,我在查询中添加了适当的条件:

...
WHERE payment_history.client_id = 258 
AND payment_history.payment_method != 'ChangeSum'
...

但在结果集中,other也为空:

enter image description here

other列包含payment_method ||空字符串时,为什么会出现以及如何使用所需方法(包括NULL)获取数据;但不带< / strong> ChangeStatus)?

4 个答案:

答案 0 :(得分:2)

LEFT JOIN时,将右侧表条件放在ON子句中。 (在WHERE时,您将获得定期INNER JOIN结果。)

SELECT 
    CASE
        WHEN COALESCE(payment_history.payment_method, '') = '' THEN 'other'
        ELSE payment_history.payment_method
    END as payment_method, 
    CASE
        WHEN SUM(paid_balance) IS NULL THEN 0.00
        ELSE SUM(paid_balance)
    END as paid_balance, 
    CASE
        WHEN SUM(sum_without_commission) IS NULL THEN 0.00
        ELSE SUM(sum_without_commission)
    END as sum_without_commission                   
FROM payment_history 
LEFT JOIN participants_list 
ON payment_history.registration_id = participants_list.registration_id 
  AND participants_list.deleted = 0 
  AND participants_list.is_reserved = 0
WHERE payment_history.client_id = 258 
GROUP BY payment_history.payment_method

答案 1 :(得分:1)

除了jarlh对left joinwhere条款的解释之外,您还可以使用coalesce()简化查询,并且可以围绕可以为空的值使用coalesce()进行比较所以他们不会返回null

select 
    coalesce(payment_history.payment_method, 'other') as payment_method
  , coalesce(sum(paid_balance),0.00) as paid_balance
  , coalesce(sum(sum_without_commission),0.00) as sum_without_commission
from payment_history 
  left join participants_list 
    on payment_history.registration_id = participants_list.registration_id 
   and participants_list.deleted = 0 
   and participants_list.is_reserved = 0
where payment_history.client_id = 258 
  and coalesce(payment_history.payment_method,'')!='ChangeSum'
group by payment_history.payment_method

比较payment_method为空时,null != 'ChangeSum'将返回null,而不是真。 Comparison Operators

扩展null比较问题:

Null被视为unknown,因此与null的比较始终为unknown,因此,如果您对null != 'ChangeSum'进行过滤,则结果不是{{1} (true),null仅包含条件为where的结果。 https://www.postgresql.org/docs/9.1/static/functions-comparison.html

truecoalesce(payment_history.payment_method,'')!='ChangeSum'时,使用true会返回payment_method,因为nullcoalesce值替换为null比较和'''' != 'ChangeSum'

答案 2 :(得分:1)

使用is distinct from

and payment_history.payment_method is distinct from 'ChangeSum'

答案 3 :(得分:0)

感谢@SqlZim和@jarlh我已经改变了我的查询。下面有一个有效的变体:

SELECT 
COALESCE(NULLIF(payment_history.payment_method, ''), 'other') AS payment_method, 
COALESCE(SUM(paid_balance), 0.00) AS paid_balance,
COALESCE(SUM(sum_without_commission), 0.00) AS sum_without_commission                  
FROM payment_history 
INNER JOIN participants_list 
ON payment_history.registration_id = participants_list.registration_id 
WHERE payment_history.client_id = 258 
AND participants_list.deleted = 0 
AND participants_list.is_reserved = 0
AND COALESCE(payment_history.payment_method, '') != 'ChangeSum'
GROUP BY payment_history.payment_method

也可以写

AND payment_history.payment_method IS DISTINCT FROM 'ChangeSum'

而不是

AND COALESCE(payment_history.payment_method, '') != 'ChangeSum'

,正如@Clodoaldo Neto提出的那样。