有条件地计算SQL中列的值,并计算空值
我有一个SQL查询,尝试在COUNT()中执行一些条件。我正在使用PostgreSQL。这是我最初的疑问:有条件地计算SQL中列的值,并计算空值,sql,postgresql,aggregate-functions,Sql,Postgresql,Aggregate Functions,我有一个SQL查询,尝试在COUNT()中执行一些条件。我正在使用PostgreSQL。这是我最初的疑问: SELECT s.schedule_ID as "schedule_ID", schedule_start, schedule_end, spots, COUNT(CASE a.schedule_ID WHEN s.schedule_ID THEN TRUE ELSE NULL END) as "takenSpots" FROM schedule
SELECT s.schedule_ID as "schedule_ID", schedule_start, schedule_end, spots,
COUNT(CASE a.schedule_ID WHEN s.schedule_ID THEN TRUE ELSE NULL END) as "takenSpots"
FROM schedules s, appointments a
GROUP BY s.schedule_ID
ORDER BY s.schedule_ID;
基本上,只有当它与schedules表中的schedule_ID匹配时,才会对来自约会的schedule_ID
进行计数。问题在于,当约会表中的a.schedule\u ID
为空时,此查询不考虑这种情况。如果为空,则不返回任何记录。我想说明空值,如果为空,则返回0
经过一些研究,我发现这样的方法一定会奏效:
SELECT s.schedule_ID as "schedule_ID", schedule_start, schedule_end, spots,
COUNT(CASE a.schedule_ID WHEN s.schedule_ID THEN TRUE WHEN NULL THEN '0' END) as "takenSpots"
FROM schedules s, appointments a
GROUP BY s.schedule_ID
ORDER BY s.schedule_ID;
但即使我检查空值,这里也没有运气,也没有返回任何记录。有人能帮我吗
我感谢你的帮助 您的CASE表达式不起作用的原因是,您使用的“short-form”只能测试相等性,而对于NULL值,它永远不会为true 因此,您需要使用:
CASE WHEN a.schedule_ID = coalesce(s.schedule_ID, a.schedule_ID) then TRUE ELSE NULL END
但是,您没有正确地连接这两个表<代码>来自a,b是一个隐式的交叉联接
在两个表之间创建笛卡尔积
似乎您正在寻找一个匹配项,然后计算匹配项的数量:
SELECT s.schedule_ID as "schedule_ID", schedule_start, schedule_end, spots,
count(a.schedule_id) "takenSpots"
FROM schedules s
LEFT JOIN appointments a on s.schedule_id = a.schedule_id
GROUP BY s.schedule_ID
ORDER BY s.schedule_ID;
外部联接将返回计划
表中的所有行,并且只返回那些与约会
表中的行相匹配的行。对于schedules
中没有约会的行,a.schedule\u id
将为空,count()
忽略这些行
假设选择列表中的所有列(除了
a.schedule\u id
)都来自schedules
表,有一种更有效的方法:首先聚合约会,然后进行外部联接:
SELECT s.schedule_id as "schedule_ID", schedule_start, schedule_end, spots,
coalesce(a.num_appointments,0) as "takenSpots"
FROM schedules s
LEFT JOIN (
select ap.schedule_id, count(*) as num_appointments
from appointments app
group by ap.schedule_id
) a on s.schedule_id = a.schedule_id
ORDER BY s.schedule_id;
这两个表之间没有联接条件。您真的打算创建笛卡尔产品吗?谢谢您的回复。不,我不打算那样做。你能再给我引路一点吗?我该怎么做?你真是一颗宝石。这就是答案。非常感谢你。