繁体   English   中英

如何选择3个最大的结果,但排除空值

[英]How to select 3 largest results, but exclude null values

我有两个表(事件和发生次数)。 每个事件在出现表中都有0个或更多条目。 我想对出现的次数求和并返回前5个结果。 只要所有事件在事件表中都有条目,我就有一些适用于此的SQL。 如果事件在事件表中没有条目,则该事件在列表顶部结束。

什么是实现此目标的正确SQL?

表定义

事件
id-整数
EventName-varchar(200)

发生次数
id-int
Event_ID-整数
时间戳记-日期时间
发生的时间-int

对于ID为1(事件名称-“上下文切换”)的事件,我可能在Occurrences表中具有相应的行:

ID:1,Event_ID:1,时间戳:'2016-08-02 05:52:00',发生次数:50
ID:8,Event_ID:1,时间戳:'2016-08-02 07:11:00',发生次数:20

我将在Occurrences表中使用其他具有相应条目的事件,以及一些没有相应条目的事件(尚未发生,不经常发生的事件等)。

下面的SQL通过对具有相同ID的所有事件的TimesOccurred列求和,从而给出前5个发生的事件。

SELECT Events.Name, t.total as Total FROM Events
LEFT JOIN 
(SELECT Occurrences.Event_ID, sum(Events.TimesOccurred) as total FROM Occurrences 
INNER JOIN Events on Events.id = Occurrents.Event_ID GROUP BY Events.id) t
on Events.id = t.Event_ID ORDER BY t.total DESC limit 5;

这可能给我

分段故障20
上下文切换10

但是,如果我有一个名为OOM且ID为3的事件,并且Occurrences表中没有Event_ID为3的条目,那么我将得到以下信息

OOM
分段故障20
上下文切换10

我尝试将查询更改为:

SELECT Events.Name, COALESCE(t.total, 0) as Total FROM Events
LEFT JOIN 
(SELECT Occurrences.Event_ID, sum(Events.TimesOccurred) as total FROM Occurrences 
INNER JOIN Events on Events.id = Occurrents.Event_ID GROUP BY Events.id) t
on Events.id = t.Event_ID ORDER BY t.total DESC limit 5;

然后返回

OOM 0
分段故障20
上下文切换10

我相信这是因为我正在对t.total进行排序,而COALESC并未将t.total设置为0(结果为空),而是返回0(结果为空)。

知道如何从发生的前5个事件中排除空值吗?

谢谢,

在Postgres中,您可以通过在排序方向后添加NULLS [LAST/FIRST]ORDER BY子句中定义对空值的处理。

另外,您只需要访问两个表一次-不需要其他派生表。

SELECT Events.Name, sum(Occurences.TimesOccurred) as Total 
FROM Events
LEFT JOIN Occurrences ON Events.id = Occurrences.Event_ID
GROUP BY 1
ORDER BY 2 DESC NULLS LAST
LIMIT 5

手册 (我的粗体强调 -您在前5个查询中获取空值的原因):

默认情况下,空值的排序方式似乎大于任何非空值。 也就是说, DESC order的默认值为NULLS FIRST ,否则 NULLS LAST。

如果在不发生任何事件时仍需要返回0(因为总共可能有5个或更少的事件),则添加COALESCE()COALESCE() -顺便说一下。


我还向GROUP BYORDER BY子句中的列添加了整数别名。

您还可以为表名创建别名,以使代码稍微缩短一点。

我建议您简化查询并使用NULLS LAST

  SELECT e.Name, sum(o.TimesOccurred) as total
  FROM Events e LEFT JOIN
       Occurrences o I
       ON Events.id = o.Event_ID
  GROUP BY e.Name
  ORDER BY total DESC NULLS LAST
  LIMIT 5;

注意,两个表之间仅需要一个联接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM