2013-12-11 85 views
1

我想從我的表中獲取數據,包括空行。例如:我想知道,如果在過去30分鐘內有一些活動。如果有什麼,那麼我可以獲取數據並且它可以工作,但是如何在沒有任何活動的情況下包含這些記錄?我所有的數據都在同一張表中。PostgreSQL - 如何從同一個表中獲取空(空)記錄?

謝謝!

╔═════╦═════════════════════╦══════╗ 
    ║ 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 ║ 
    ╚═════╩═════════════════════╩══════╝ 

我想得到狀態4,在這種情況下,按SRV分組狀態4的標誌數。當在指定的時間段內沒有標誌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 
+3

可以顯示錶格的結構,數據和結果的示例以及您已經嘗試寫入的查詢嗎? –

回答

0

嘗試用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,然後用NULL替換0:

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 

但此查詢將始終讀取整個表,所以可能會ineficcient。

以下版本讀取所有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 
+0

不幸的是,它不起作用:(我得到了相同的結果,因爲我會用count(*)。 –

+0

@ user3091257對不起,查詢中有錯誤,我糾正了它們,並添加了一些新的查詢 – krokodilko

+0

謝謝!這就是我應該達到的目標:)精彩的作品。我正在考慮使用「加入」,但我是SQL的新手。我可以理解如何連接兩個不同的表,但我不知道你可以將表連接到它自己。此外,外連接是我需要學習的東西,因爲它對我來說有點複雜(現在)。 –

0

我會做到這一點真的很簡單 - 首先,我會用一些表的srv所有可能的值(我使用的陣列,以保持它的簡單),然後就指望所有標誌那srv值:

SELECT 
    s.x, CASE WHEN s.num = 0 THEN NULL ELSE s.num END 
FROM (
    SELECT x, (
     SELECT COUNT(1) 
     FROM table1 
     WHERE flag = 4 AND date >= NOW() - INTERVAL '10m' AND srv = x 
    ) AS num 
    FROM 
     UNNEST(ARRAY[1, 2, 3]) AS x 
    ORDER by x) AS s; 

這將返回:

x | num 
---+----- 
1 | 2 
2 |  
3 | 2 
(3 rows) 

如果你有一些表srv值,只是 此表的名稱替換UNNEST(ARRAY[..])