2014-10-02 46 views
0

有兩個表A和B與下面的列和樣本數據最後一小時數和最後接收的

Id Code  Name  Active 
--------------------------------- 
1  A1  Apple  t 
2  B2  Banana  t 
3  C1  Cherry  f 
4  D2  Date  t 

Aid    Received  
----------------------------------- 
1  2014-10-02 10:24:55.095714 
2  2014-10-02 10:54:53.226128 
3  2014-10-02 15:39:59.683531 
1  2014-10-02 15:39:59.862021 
4  2014-10-02 15:42:19.923144 
4  2014-10-02 15:49:29.964731 
1  2014-10-02 15:53:27.586373 

Aid是來自表的外鍵A

我需要顯示的所有名字,在過去一小時每個接收的最後接收的時間數和

用於採樣數據的預期輸出如下

Name  Count   LastReceived  
------------------------------------------- 
Banana  0  2014-10-02 10:54:53.226128 
Apple  2  2014-10-02 15:53:27.586373 
Date  1  2014-10-02 15:49:29.964731 

查詢我寫到目前爲止如下

SELECT 
    A.name, 
    COUNT(B.Aid) AS Count, 
    MAX(B.Received) AS LastReceived 
FROM 
    A 
FULL OUTER JOIN 
    B 
ON A.id = B.Aid 
WHERE B.Received > (NOW() - INTERVAL '1 hour') AND A.Active = TRUE --approx. 3pm to 4pm 10/2/2014 
GROUP BY A.name 
ORDER BY Count, A.name 

我沒有得到預期的輸出與此查詢。我應該如何修改查詢以獲得預期的輸出?

編輯

我需要零計數顯示首字母順序排列,然後按字母順序休息用的那些命令的結果。我可以在單個查詢中執行此操作嗎?我知道加入ORDER BY Count, A.name是行不通的。

回答

3

您遇到的問題是where子句排除您想要考慮的最後一次接收日期的行。解決它的方法之一是有條件聚集:

select 
    a.name, 
    sum(case when b.Received > (now() - interval '1 hour') then 1 else 0 end) AS Count, 
    max(b.Received) as LastReceived 
from 
    a 
    left outer join 
    b 
    on a.id = b.aid 
where 
    a.Active = true 
group by 
    a.name 
order by 
    case when sum(case when b.Received > (now() - interval '1 hour') then 1 else 0 end) = 0 then 0 else 1 end, 
    a.name 

的方式通過作品的順序可能是更容易拉出的公共表表達式來理解:

with x as (
    select 
    a.name, 
    sum(case when b.Received > '2014-10-02 15:00:00' then 1 else 0 end) AS Count, 
    max(b.Received) as LastReceived 
    from 
    a 
     left outer join 
    b 
     on a.id = b.aid 
    where 
    a.Active = true 
    group by 
    a.name 
) select 
    x.name, 
    x.count, 
    x.lastreceived 
from 
    x 
order by 
    case when x.Count = 0 then 0 else 1 end, 
    x.name 

Example SQLFiddle

+0

我編輯了這個問題。你可以修改答案以包含提到的順序嗎? – Ram 2014-10-03 14:55:32

+0

@Srikanth我已添加 – Laurence 2014-10-03 18:23:16

+0

謝謝。有用。你能解釋一下你在外面的'CASE WHEN'上做了什麼嗎? – Ram 2014-10-03 18:29:58

0

你查詢幾乎是正確的,除非你需要一個LEFT JOIN,如表A是你的驅動關係:

SELECT a.name, 
     count(b.aid), 
     max(b.received) AS LastReceived 
    FROM a 
    LEFT JOIN b ON a.id=b.aid AND b.received > now()-INTERVAL '1 hour' 
WHERE a.active 
GROUP BY a.name 
ORDER BY a.name; 

此外,您是否篩選出WHERE子句中的結果非常重要,在您的情況下,它會跳過可能產生零計數的所有條目,或者將篩選器置於連接條件(如上所述)中。

+0

謝謝。我沒有得到零計數的物品的LastReceived時間戳 – Ram 2014-10-03 13:57:56

+0

@Srikanth:Hm,如果在指定的時間間隔內沒有收到任何東西,則「LastReceived」的含義是什麼? – vyegorov 2014-10-03 14:05:37

+1

在表B中,在過去一小時內沒有收到香蕉(約。下午3點到4點10/2/2014)所以計數將爲零,但最後收到的香蕉是在2014年10月2日上午11點左右,所以應該顯示時間 – Ram 2014-10-03 14:37:06

相關問題