Ben
Ben

Reputation: 5777

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

I am getting an error in a query:

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

I didn't write the query, and not sure what union does so not sure how to fix it.

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

Upvotes: 1

Views: 125

Answers (2)

John Ruddell
John Ruddell

Reputation: 25842

you cannot order by an aggregate function and you dont have quotes around your $id which php requires... see my note at the end about sql injection

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

instead

try changing it to just mostrecent because you already pulled out the max and gave it the alias mostrecent.. you can reference an alias in anything after the WHERE so GROUP BY and beyond including the ORDER BY

ORDER BY mostrecent DESC

so the final query should look like this...

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

NOTE

this query is vunerable to sql injection and I would recommend you parameterize your query and bind the $id to the query afterwards

you should read my post about writing a safer query...

Upvotes: 2

Raj More
Raj More

Reputation: 48016

Both your inner queries, and your outer query should be reworked to include both columns on the GROUP BY instead of just one:

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

Upvotes: 0

Related Questions