postgresql:附加的 WHERE 子句隐藏了行
postgresql: additional WHERE-clause hides rows
我的 SQL-请求加入 2 tables,结果是付款金额,按付款方式分组。 payment_history
table 中存在付款方式:BlueMedia、Transferuj、BankPayment 和 ChangeSum。 payment_history.payment_method
列也可以包含空字符串或 NULL
- 在这种情况下,我想将其检索为 'other' 值。
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的当前客户不存在):
other
表示记录存在于 payment_history
中,其中 payment_method
是 NULL
或空字符串。
我不想检索记录,支付方式是ChangeSum
。所以,我在查询中添加了适当的条件:
...
WHERE payment_history.client_id = 258
AND payment_history.payment_method != 'ChangeSum'
...
但在结果集中 other
也是空的:
为什么会出现这种情况,我该如何使用所需的方法获取数据(包括 other
,当 payment_method
列包含 NULL
|| 空字符串;但 没有 ChangeStatus
)?
当LEFT JOIN
时,把右边的table条件放在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
除了 jarlh 已解释的 left join
和 where
子句之外,您还可以使用 coalesce()
简化查询,并且可以在可为 null 的值周围使用 coalesce()
用于比较,因此它们不会 return 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时,null != 'ChangeSum'
将returnnull
,不成立。 Comparison Operators
扩展 null
比较问题:
Null
被视为 unknown
,因此与 null
的比较始终是 unknown
,因此如果您过滤 null != 'ChangeSum'
,结果不是 true
(即 null
),而您的 where
仅包含您的条件为 true
的结果。 https://www.postgresql.org/docs/9.1/static/functions-comparison.html
当 payment_method
为 null
时使用 coalesce(payment_history.payment_method,'')!='ChangeSum'
returns true
,因为 coalesce
正在替换 null
值与 ''
进行比较, '' != 'ChangeSum'
是 true
.
感谢@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 所建议的那样。
and payment_history.payment_method is distinct from 'ChangeSum'
我的 SQL-请求加入 2 tables,结果是付款金额,按付款方式分组。 payment_history
table 中存在付款方式:BlueMedia、Transferuj、BankPayment 和 ChangeSum。 payment_history.payment_method
列也可以包含空字符串或 NULL
- 在这种情况下,我想将其检索为 'other' 值。
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的当前客户不存在):
other
表示记录存在于 payment_history
中,其中 payment_method
是 NULL
或空字符串。
我不想检索记录,支付方式是ChangeSum
。所以,我在查询中添加了适当的条件:
...
WHERE payment_history.client_id = 258
AND payment_history.payment_method != 'ChangeSum'
...
但在结果集中 other
也是空的:
为什么会出现这种情况,我该如何使用所需的方法获取数据(包括 other
,当 payment_method
列包含 NULL
|| 空字符串;但 没有 ChangeStatus
)?
当LEFT JOIN
时,把右边的table条件放在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
除了 jarlh 已解释的 left join
和 where
子句之外,您还可以使用 coalesce()
简化查询,并且可以在可为 null 的值周围使用 coalesce()
用于比较,因此它们不会 return 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时,null != 'ChangeSum'
将returnnull
,不成立。 Comparison Operators
扩展 null
比较问题:
Null
被视为 unknown
,因此与 null
的比较始终是 unknown
,因此如果您过滤 null != 'ChangeSum'
,结果不是 true
(即 null
),而您的 where
仅包含您的条件为 true
的结果。 https://www.postgresql.org/docs/9.1/static/functions-comparison.html
当 payment_method
为 null
时使用 coalesce(payment_history.payment_method,'')!='ChangeSum'
returns true
,因为 coalesce
正在替换 null
值与 ''
进行比较, '' != 'ChangeSum'
是 true
.
感谢@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 所建议的那样。
and payment_history.payment_method is distinct from 'ChangeSum'