有条件地计算SQL中列的值,并计算空值

有条件地计算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

我有一个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 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;

这两个表之间没有联接条件。您真的打算创建笛卡尔产品吗?谢谢您的回复。不,我不打算那样做。你能再给我引路一点吗?我该怎么做?你真是一颗宝石。这就是答案。非常感谢你。