2017-07-03 74 views
1
  POSTS 
[ id - post - content ] 
---------------------------- 
[ 1 - 1post1 - 1content1] 
[ 2 - 1post2 - 2content2] 



     VOTES 
    [ id - pid] 
    ------------ 
    [ 1 - 1] 
    [ 2 - 1] 
    [ 3 - 1] 
    [ 4 - 2] 
    [ 5 - 2] 

1post1 = 3 votes 
2post2 = 2 votes 

當我嘗試此查詢ORDER BY和別名COUNT()在一個查詢

$query = "SELECT a.title, a.content, b.COUNT(id) FROM posts a, votes b WHERE id = :id ORDER BY b.COUNT(id)"; 

它不工作,並給了我這個錯誤

FUNCTION b.COUNT does not exist. Check the 'Function Name Parsing and Resolution 

是否有一個更好的如何做到這一點?我想過使用UNION ALL是這樣

$query = "SELECT title, content, COUNT(id) FROM posts WHERE id = :id 
UNION ALL 
SELECT COUNT(id) FROM votes WHERE pid = :id"; 

,但我將無法使用ORDER BY COUNT(id)的第一部分,這是我想訂購取決於第二部分問題就在這裏。

+0

要清楚,你是否試圖選擇按'票數'排序的'posts'?什麼是表結構? –

+2

你是指'count(b.id)'? – xQbert

+0

@NiettheDarkAbsol推出了一個示例表。 –

回答

0
  1. 它看起來像帖子/投票之間有一個關係,所以需要連接。這是你現在正在做的交叉連接看起來不正確。因爲它會從結果中獲得結果(2)和結果中的(5),並將它們相乘,得到10條記錄。您需要加入,以便引用來自投票的postID。
  2. count是一個函數,因此它被用作count(table.field)來計算特定列中的值或計數(*)中的值,以計算表中的記錄數。
  3. 加入兩張表時;一定要別名列(在你的情況下ID都存在於兩者中,這樣在指定什麼表後ID是
  4. 當使用聚合例如COUNT()時,如果您有非聚合字段,則需要使用group by(例如ID或交在你的例子)

因此,也許...(ANSI 92)

SELECT P.ID, P.Post, count(V.ID) as No_Votes 
FROM Posts P 
INNER JOIN Votes V 
on V.PID = P.ID 
WHERE P.ID = :id 
GROUP BY P.ID, P.Post 
ORDER BY No_votes -- due to order of operation we can use the column alias in an order by. 

還是......(ANSI 87)

SELECT P.ID, P.Post, count(V.ID) as No_Votes 
FROM Posts P, Votes V 
WHERE V.PID = P.ID 
    AND P.ID = :id 
GROUP BY P.ID, P.Post 
ORDER BY No_votes 

也許你婉所有帖子甚至沒有投票,所以也許你需要使用OUTER JOIN(右/左而不是內部,取決於你的內容):你的示例和預期結果不顯示任何內容,所以我從這裏開始)

+0

「FROM table x,table y'和'FROM table x INNER JOIN table y'之間有什麼區別? –

+0

x,y是'交叉連接'(沒有關於X,y的標準),因此你得到10條記錄。 'INNER JOIN' on ...顯示一個關係,因此記錄數不能超過其中一個表中的記錄數。所以最多5條記錄可能會被返回,因爲我們按x方向分組並計算y方,所以我們只能得到2條記錄。交叉連接會將所有X與所有Y結婚,因此Post1將與投票1-5相關聯,並且Post2也將與投票1-5相關聯。在你的問題中給出預期的結果後,我不認爲你就是這樣。 – xQbert

+0

','符號也是ANSI 87標準,其中如'INNER JOIN'或'CROSS JOIN'是ANSI 92標準既工作;只是不要混合它們。由於您沒有在您的示例中說明x/y如何關聯的where子句,因此會遇到交叉連接結果。 – xQbert

1

只要刪除b。從前數(id)...你正在使用一個函數,而不是一個表別名。

+0

這是兩個不同的表相關。 –

+0

@ Calibur對你的陳述是錯誤的..因爲cbell說,你需要從b.count(...)中刪除b,它應該是count(b.id) – fabricio

+0

否。答案是肯定的。您必須從聚合函數中刪除前綴。它是COUNT(b.id) - 不是b.COUNT(id)。 – fhossfel