SQL查询出错,不确定如何修复

时间:2014-10-15 12:47:09

标签: php mysql sql

我在查询中收到错误:

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group by `messages`.`to_id` UNION SELECT `users`.`username` as 'subj' at line 13

我没有编写查询,也不确定联合会做什么,所以不确定如何修复它。

select `thread`.`subject`,
       `thread`.`id`, 
       max(`thread`.`mostrecent`) as 'mostrecent',
       sum(`thread`.`from` + `thread`.`to`) as 'messages' 
from (
    SELECT `users`.`username` as 'subject', 
           `messages`.`to_id` as 'id' , 
           max(`messages`.`created`) as 'mostrecent',
           count(*) as 'from',
           0 as 'to' from `messages` 
           join `users` on `messages`.`to_id` = `users`.`id` 
           where `messages`.`from_id` = $id 
           group by `messages`.`to_id` 
    UNION 
    SELECT `users`.`username` as 'subject',
           `messages`.`from_id` as 'id', 
           max(`messages`.`created`) as 'mostrecent', 
           0 as 'from', 
           count(*) as 'to' from `messages` 
           join `users` on `messages`.`from_id` = `users`.`id` 
           where `messages`.`to_id` = $id
           group by `messages`.`from_id`
) as thread group by `thread`.`subject` order by max(`thread`.`mostrecent`) desc

2 个答案:

答案 0 :(得分:2)

你不能通过聚合函数订购,并且你没有关于PHP所需的$ id的引号...最后看看关于sql注入的注释

SELECT `thread`.`subject`,
       `thread`.`id`, 
       max(`thread`.`mostrecent`) as 'mostrecent',
       sum(`thread`.`from` + `thread`.`to`) as 'messages' 
from (
    SELECT `users`.`username` as 'subject', 
           `messages`.`to_id` as 'id' , 
           max(`messages`.`created`) as 'mostrecent',
           count(*) as 'from',
           0 as 'to' from `messages` 
           join `users` on `messages`.`to_id` = `users`.`id` 
           where `messages`.`from_id` = $id 
-- ------------------------------------^---^ = needs quotes
           group by `messages`.`to_id` 
    UNION 
    SELECT `users`.`username` as 'subject',
           `messages`.`from_id` as 'id', 
           max(`messages`.`created`) as 'mostrecent', 
           0 as 'from', 
           count(*) as 'to' from `messages` 
           join `users` on `messages`.`from_id` = `users`.`id` 
           where `messages`.`to_id` = $id
-- ----------------------------------^---^ = needs quotes
           group by `messages`.`from_id`
) as thread group by `thread`.`subject` order by max(`thread`.`mostrecent`) desc
-- -----------------------------------------------^------------------------^ = bad

不是

尝试将其更改为最新版本,因为您已经拉出最大值并为其提供了最新的别名..您可以在WHERE之后的任何内容中引用别名,因此GROUP BY及其后包括ORDER BY

ORDER BY mostrecent DESC

所以最终的查询应该是这样的......

SELECT 
    `thread`.`subject`,
    `thread`.`id`, 
    MAX(`thread`.`mostrecent`) AS 'mostrecent',
    SUM(`thread`.`from` + `thread`.`to`) AS 'messages' 
FROM 
(   SELECT 
        `users`.`username` AS 'subject', 
        `messages`.`to_id` AS 'id' , 
        MAX(`messages`.`created`) AS 'mostrecent',
        COUNT(*) AS 'from',
        0 AS 'to' 
    FROM `messages` 
    JOIN `users` ON `messages`.`to_id` = `users`.`id` 
    WHERE `messages`.`from_id` = '$id' 
    GROUP BY `messages`.`to_id` 

    UNION 

    SELECT 
        `users`.`username` AS 'subject',
        `messages`.`from_id` AS 'id', 
        MAX(`messages`.`created`) AS 'mostrecent', 
        0 AS 'from', 
        COUNT(*) AS 'to' 
    FROM `messages` 
    JOIN `users` ON `messages`.`from_id` = `users`.`id` 
    WHERE `messages`.`to_id` = '$id'
    GROUP BY `messages`.`from_id`
) AS thread 
GROUP BY `thread`.`subject` 
ORDER BY mostrecent DESC

这个查询对sql注入很有用,我建议你参数化你的查询并在之后将$ id绑定到查询

您应该阅读my post关于编写更安全的查询...

答案 1 :(得分:0)

您的内部查询和外部查询都应该重新编写,以便在GROUP BY上包含两列而不只是一行:

select 
    `thread`.`subject`,
    `thread`.`id`, 
    max(`thread`.`mostrecent`) as 'mostrecent',
    sum(`thread`.`from` + `thread`.`to`) as 'messages' 
from 
(
    SELECT 
        `users`.`username` as 'subject', 
        `messages`.`to_id` as 'id' , 
        max(`messages`.`created`) as 'mostrecent',
        count(*) as 'from',
        0 as 'to' 
    FROM `messages` 
    JOIN `users` on `messages`.`to_id` = `users`.`id` 
    WHERE `messages`.`from_id` = $id 
    GROUP BY `users`.`username`, `messages`.`to_id` 
UNION 

    SELECT 
        `users`.`username` as 'subject',
        `messages`.`from_id` as 'id', 
        max(`messages`.`created`) as 'mostrecent', 
        0 as 'from', 
        count(*) as 'to' 
    FROM `messages` 
    JOIN `users` on `messages`.`from_id` = `users`.`id` 
    WHERE `messages`.`to_id` = $id
    GROUP BY `users`.`username`, `messages`.`from_id`
) as thread 
GROUP BY `thread`.`subject`, `thread`.`id`
ORDER BY max(`thread`.`mostrecent`) desc