This is my query:
SELECT `p`.`name` AS 'postauthor', `a`.`name` AS 'authorname',
`fr`.`pid`, `fp`.`post_topic` AS 'threadname', `fr`.`reason`
FROM `z_forum_reports` `fr`
LEFT JOIN `forums` `f` ON (`f`.`id` = `fr`.`pid`)
LEFT JOIN `forums` `fp` ON (`f`.`first_post` = `fp`.`id`)
LEFT JOIN `ps` `p` ON (`p`.`id` = `f`.`author_guid`)
LEFT JOIN `ps` `a` ON (`a`.`account_id` = `fr`.`author`)
My problem is this left join:
SELECT `a`.`name`, `a`.`level`
[..]
LEFT JOIN `ps` `a` ON (`a`.`account_id` = `fr`.`author`)
Since, in case a
has MANY rows and it'll return like in my case:
NAME | LEVEL
Test1 | 1
Test2 | 120
Test3 | 2
Test4 | 1
I want it to select a.name
with order
of level desc
and limit 1, so it'll return the name of higher level
where (a.account_id = fr.author)
.
Hope you got me. If not, feel free to post a comment.
The plus sign is Oracle syntax for an outer join. There isn't a minus operator for joins. An outer join means return all rows from one table. Also return the rows from the outer joined where there's a match on the join key.
1 Answer. The order doesn't matter for INNER joins. As long as you change your selects from SELECT * to SELECT a.
Left joins can increase the number of rows in the left table if there are multiple matches in the right table.
The LEFT JOIN keyword returns all records from the left table (table1), and the matching records from the right table (table2). The result is 0 records from the right side, if there is no match.
Try replacing:
LEFT JOIN ps a ON a.account_id = fr.author
with:
LEFT JOIN ps a
ON a.PrimaryKey --- the Primary Key of ps
= ( SELECT b.PrimaryKey
FROM ps AS b
WHERE b.account_id = fr.author
ORDER BY b.level DESC
LIMIT 1
)
Replace the LEFT JOIN clause with something like:
...
LEFT JOIN (SELECT b.account_id, b.name
FROM (SELECT c.account_id, MAX(c.level) AS level
FROM ps AS c
GROUP BY c.account_id) AS d
JOIN ps AS b ON b.account_id = d.account_id AND b.level = d.level
) AS a
ON (a.account_id = fr.author)
...
This will still return multiple rows if there were several rows in ps
with the same account ID and the same level and that level was the maximum level:
NAME | LEVEL
Test1 | 1
Test2 | 120
Test3 | 2
Test4 | 1
Test5 | 120
If this situation can arise, then you have to decide what you want to do - and tune the query appropriately. For example, you might decide to use MAX(b.name)
with a GROUP BY clause to arbitrarily select the alphabetically later of the two names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With