有条件地计算 SQL 中列的值并考虑 NULL 值

Conditionally COUNT the Value of a Column in SQL and Account for NULL Value

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

基本上,只有当它与日程 table 中的 schedule_ID 相匹配时,才会将 schedule_ID 计入约会。问题是此查询不考虑约会 table 中 a.schedule_ID 为空的情况。当它为 null 时,returns 没有 records.I 想要考虑 null 值,如果它为 null,则 return 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;

但是运气不好,即使我检查 NULL 值,仍然没有记录 return。有人可以帮我吗?

感谢您的帮助!

您的 CASE 表达式不起作用的原因是因为您使用的“简写形式”只能测试是否相等,这对于 NULL 值永远不会成立。

所以你需要使用:

CASE WHEN a.schedule_ID = coalesce(s.schedule_ID, a.schedule_ID) then TRUE ELSE NULL END

但是您没有正确加入两个 table。 from a,b 是一个隐式 cross join 在两个 table 之间创建笛卡尔积。

您似乎在寻找一个outer join,然后计算匹配的数量:

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;

外部联接将 return 来自 schedules table 的所有行,并且只有那些与 appointments table 匹配的行。对于 schedules 中没有约会的行,a.schedule_id 将为空,而 count() 将忽略这些行。


假设 SELECT 列表中的所有列(a.schedule_id 除外)都来自 schedules table,有一种稍微更有效的方法:聚合先约会,再做外连接:

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;