I’m trying to run an SQL command on my database. I have two tables, one for users, another one for posts. I want to find last post of each user. I tried following:
SELECT b.`username`, b.`id`, c.`home`, c.`text` FROM `sunlight-users` AS b LEFT JOIN `sunlight-posts` AS c ON b.`id` = c.`author` WHERE b.`group` = 1 OR b.`group`=3 OR b.`group`= 5 OR b.`group` = 10 OR b.`group` = 14 OR b.`group` = 23 OR b.`group` = 25 ORDER by c.`time` DESC GROUP BY b.`username`
It fails with error “your syntax is weird near GROUP BY b.username
on line 5″.
I tried to run the command with while loop (on the webpage) like this:
$query = DB::query("SELECT * FROM `"._mysql_prefix."-users` WHERE `group` = 1 OR `group` = 3 OR `group` = 5 OR `group` = 10 OR `group` = 14 OR `group` = 23 OR `group` = 25"); while($item = DB::row($query)) { $post = DB::query("SELECT type,home,xhome,author,time FROM `"._mysql_prefix."-posts` WHERE ".$knihy." AND `author` = ".item['id']." ORDER BY `time` DESC LIMIT 1"); switch($post['home']){ case 2: //code break; case 3: //code break; default: //code }
But it looks like the second query is completely ignored, I get default values even though manually typing the query into database gets 2 or 3. I know that running like 50 queries in a loop probably isn’t a good idea, that’s why I’m trying to do it all at once. This code:
SELECT b.`username`, b.`id`, c.`home`, c.`text` FROM `sunlight-users` AS b LEFT JOIN `sunlight-posts` AS c ON b.`id` = c.`author` WHERE b.`group` = 1 OR b.`group`=3 OR b.`group`= 5 OR b.`group` = 10 OR b.`group` = 14 OR b.`group` = 23 OR b.`group` = 25 ORDER by c.`time` DESC
results in
+----+----------+------+------+ | id | username | home | text | +----+----------+------+------+ | 1 | user1 | 2 | .... | | 1 | user1 | 3 | aaaa | | 0 | user0 | 4 | .... | +----+----------+------+------+
The order is correct, I want just the upper row for each user. I’d appreciate any help.
Advertisement
Answer
You actually need to filter, not group. You can do this with a correlated subquery:
select u.username, u.id, p.home, p.text from sunlight_users u left join sunlight_posts p on u.id = p.author and p.time = (select max(p1.time) from sunlight_posts p1 where p1.author = u.id) where u.group in (1, 3, 5, 10, 14, 23, 25) order by u.username
In MySQL 8.0, you can use window functions:
select * from ( select u.username, u.id, p.home, p.text, row_number() over(partition by u.id order by p.time desc) rn from sunlight_users u left join sunlight_posts p on u.id = p.author where u.group in (1, 3, 5, 10, 14, 23, 25) ) t where rn = 1 order by u.username