PostgreSQL-如何从同一个表中获取空(null)记录?

PostgreSQL-如何从同一个表中获取空(null)记录?,postgresql,Postgresql,我想从我的表中获取数据,包括空行。例如:我想知道,在过去的30分钟里是否有一些活动。如果有什么,那么我可以得到数据,它也可以工作,但是如何在没有任何活动的情况下包含这些记录呢?我所有的数据都在同一张表中 谢谢 ╔═════╦═════════════════════╦══════╗ ║ SRV ║ DATE ║ FLAG ║ ╠═════╬═════════════════════╬══════╣ ║ 1 ║ 2013-01-01

我想从我的表中获取数据,包括空行。例如:我想知道,在过去的30分钟里是否有一些活动。如果有什么,那么我可以得到数据,它也可以工作,但是如何在没有任何活动的情况下包含这些记录呢?我所有的数据都在同一张表中

谢谢

    ╔═════╦═════════════════════╦══════╗
    ║ SRV ║        DATE         ║ FLAG ║
    ╠═════╬═════════════════════╬══════╣
    ║   1 ║ 2013-01-01 08:10:12 ║    4 ║
    ║   1 ║ 2013-01-01 08:11:24 ║    4 ║
    ║   1 ║ 2013-01-01 08:12:01 ║    5 ║
    ║   1 ║ 2013-01-01 08:12:14 ║    5 ║
    ║   2 ║ 2013-01-01 08:20:44 ║    4 ║
    ║   2 ║ 2013-01-01 08:23:11 ║    5 ║
    ║   1 ║ 2013-01-01 08:24:09 ║    4 ║
    ║   1 ║ 2013-01-01 08:28:54 ║    5 ║
    ║   1 ║ 2013-01-01 08:30:01 ║    4 ║
    ║   3 ║ 2013-01-01 08:32:31 ║    4 ║
    ║   3 ║ 2013-01-01 08:32:45 ║    4 ║
    ║   1 ║ 2013-01-01 08:35:21 ║    4 ║
    ╚═════╩═════════════════════╩══════╝
我想得到在过去10分钟内状态为4的标志数量,在这种情况下,按SRV分组。当在指定的时间段内没有标志4时,应该有SRV和NULL值的记录。在这种情况下,我的查询应返回:

╔═════╦═══════╦══╗
║ SRV ║ COUNT ║  ║
╠═════╬═══════╬══╣
║   1 ║ 2     ║  ║
║   2 ║ NULL  ║  ║
║   3 ║ 2     ║  ║
╚═════╩═══════╩══╝
我能够使用以下方法计算现有标志:

select srv, count(*)
from table1
where flag=4 and date >= now() - interval '10m'
group by svr
order by 1

尝试使用SUM,这将返回0

select srv, SUM( CASE WHEN flag=4 THEN 1 ELSE 0 END )
from table1
where date >= now() - interval '10m'
group by svr
order by 1
如果确实需要NULL,请将0替换为NULL:

select srv, 
       CASE SUM( CASE WHEN flag=4 THEN 1 ELSE 0 END )
            WHEN 0 THEN NULL
            ELSE SUM( CASE WHEN flag=4 THEN 1 ELSE 0 END )
       END
from table1
where date >= now() - interval '10m'now() - interval '10m'
group by svr
order by 1
如果在过去30分钟内没有具有某些SRV值的记录,则上述查询不会列出此SRV。 要更正此问题,可以使用以下查询:

select srv, 
       SUM( CASE WHEN flag=4 AND date >= (now() - interval '10m')
            THEN 1 ELSE 0 END )
from table1
group by srv
order by 1
但是这个查询总是读取整个表,因此可能是无效的。 如果SRV列上有索引,则以下版本将读取所有SRV值,此操作应快速,并且在过去30分钟内仅对表的子集执行聚合,因此可能比前一个更快:

SELECT q1.srv, q2.cnt
FROM (
   SELECT DISTINCT srv
   FROM table1
) q1
LEFT JOIN (
  select srv, count( * ) as cnt
  from table1
  where flag=4 AND date >= now() - interval '10m'
  group by svr
) q2
ON q1.srv = q2.srv

我会非常简单地做到这一点-首先,我会使用一些表格,其中包含我使用的数组的所有可能的srv值,以便保持简单,然后只计算该srv值的所有标志:

这将返回:

 x | num 
---+-----
 1 |   2
 2 |    
 3 |   2
(3 rows)
如果在某些表中有srv值,只需将UNNESTARRAY[…]替换为
此表的名称。

能否显示表的结构、数据和结果的示例,以及您尝试编写的查询?不幸的是,它不起作用:我得到的结果与使用count*@user3091257时得到的结果相同。很抱歉,查询中出现了错误。我更正了它们,并添加了一些新的查询。谢谢!这就是我应该达到的目标:工作出色。我曾考虑过使用join,但我是SQL的新手。我可以理解如何连接两个不同的表,但我不知道可以将表连接到自身。另外,外部连接是我需要学习的东西,因为它现在对我来说有点复杂。
 x | num 
---+-----
 1 |   2
 2 |    
 3 |   2
(3 rows)