2017-07-03 14 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