2015-05-22 30 views
0

我有兩個表:如何返回最大或NULL,如果在沒有留下任何值JOIN

page 
p_key name 
1  home 
2  projects 
3  contacts 

article 
p_key page_id  seq (+ other article content fields) 
1   1   1 
2   1   2 
3   1   3 
4   2   1 
5   2   2 

article.seq指定哪些文章出現在頁面上的順序。

我需要一個查詢,它將返回包含page.p_key和該頁面上文章的當前最大article.seq的單個記錄,如果該頁面沒有文章,則返回NULL。

目前我有:

SELECT p.p_key, a.seq FROM page p 
LEFT JOIN article a ON p.p_key = a.page_Id 
WHERE a.seq = 
    (SELECT MAX(seq) FROM article a2 
    WHERE a2.page_id = 1); 

這可以正確處理p.p_key的這個值,返回[1,3]

但是,如果一個頁面沒有物品(例如,如果我改變「 WHERE a2.page_id = 1'到'WHERE a2.page_id = 3')查詢返回沒有記錄。我需要的是它返回[3,NULL](我正在尋找一個LEFT JOIN)。

我承認我的SQL有點生疏,那麼我該如何實現呢?

+1

位置更改到與 – Strawberry

+0

問題是where子句使加入就好像它是一個內部聯接。由於a.seq max將消除空值。你可以通過將限制作爲連接的一部分施加在表上來解決這個問題,所以限制在連接發生之前施加,允許空值。 – xQbert

+0

如果我將第一個WHERE更改爲AND,它將返回多行 - 我只想要一個行(對於指定的頁面)。 – nakb

回答

0

從描述你想要什麼,我不明白你的查詢中的a2.page_id = 1。以下應返回你所要求的:

SELECT p.p_key, 
     (SELECT MAX(a.seq) 
     FROM article a 
     WHERE p.p_key = a.page_Id 
     ) as seq 
FROM page p ; 

出於性能考慮,我建議在article(page_Id, seq)的索引。

編輯:

對於特定的頁面,你會放一個WHERE子句中查詢:

SELECT p.p_key, 
     (SELECT MAX(a.seq) 
     FROM article a 
     WHERE p.p_key = a.page_Id 
     ) as seq 
FROM page p 
WHERE p.p_key = $page; 
+0

如果我添加了一個最終的WHERE,它可以工作:WHERE p.p_key = 1(1明顯是一個參數)。如果你可以修改你的答案,我會將其標記爲答案。謝謝。 – nakb

+0

問題 - 與[我的答案](http://stackoverflow.com/a/30398791/812837)相比,MySQL是否有這樣做(nt?)會改變性能方面?當然,這是一個簡單的設置(並且有多種方式來編寫這個)... –

+0

使用'where'子句,性能應該類似。如果沒有'where'子句,相關的子查詢就可以利用'article'上的索引來進行聚合,所以沒有單獨的聚合步驟。所以,事實上,有些東西是MySQL無法做到的,那就是提供了實際使用索引的替代聚合算法。 –

0

其他一般的方式做,這是一個GROUP BY與加盟,大多數聚合函數將返回空結果爲空源數據:

SELECT Page.p_key, MAX(Article.seq) 
FROM Page 
LEFT JOIN Article 
     ON Article.page_id = Page.p_key 
-- WHERE Page.p_key = 1 
GROUP BY Page.p_key 

返回前pected結果:

p_key MAX(Article.seq)  
1  3 
2  2 
3  (null) 

SQL Fiddle Demo

相關問題