Reputation: 5777
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 SELECTusers
.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
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
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
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
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