MySQL Wrong ORDER BY - mysql

SELECT `player`.`cid`, `player`.`k`, `player`.`d`, `gg`.`gg_id`, `gg`.`name`, `gg`.`img`, `cc`.`cid`, `cc`.`name`, `cc`.`class`, `cc`.`gg_id`
FROM `player`
LEFT JOIN `cc` ON `cc`.`cid` = `player`.`cid`
LEFT JOIN `gg` ON `gg`.`gg_id` = `cc`.`gg_id`
ORDER BY (`k`-`d`) DESC
i want to order by the K minus the D values, but im not getting it correctly
what im a doing wrong? with or without DESC/ASC, its wrong

Try:
SELECT (player.k-player.d), player.cid, player.k, player.d, gg.gg_id, gg.name, gg.img, cc.cid, cc.name, cc.class, cc.gg_idFROM player LEFT JOIN cc ON cc.cid = player.cid LEFT JOIN gg ON gg.gg_id = cc.gg_id ORDER BY (player.k-player.d) DESC
I did a quick query of my own and the results appear to be unordered (despite the fact the were) until I added the SELECT (player.k-player.d). MySQL also complained about ommiting the table name in the ORDER BY clause.

Related

Subquery with joins - need help returning rows even if empty - MySQL

okay guys, this is a big one that’s confusing as hell.
I’m creating a forum type dealio: I have an array of Topics and each topic has an array of Posts associated with the Topic. The Topics list page should show the latest Post from that specific Topic. (Each topic is in a category as well)
Topic Latest post
Check out my page John Smith - 10:00 PM
MYSQL
select `ct`.*, `a`.`username`, `x`.* from `community-topics` as `ct`
inner join `community-categories` as `cc` on `cc`.`communityCategoryId` = `ct`.`refCategoryId`
inner join `authentication` as `a` on `a`.`userId` = `ct`.`refCreatedBy`
inner join (
select `a2`.`username` AS lastPostUsername, `cp`.`createdAt` AS lastPostCreatedAt,
`cp`.`body`, `cp`.`refTopicId` from `community-posts` as `cp`
inner join `authentication` as `a2` on `a2`.`userId` = `cp`.`refCreatedBy`
order by `cp`.`createdAt` desc limit 1
) as x on `x`.`refTopicId` = `ct`.`communityTopicId`
where `cc`.`name` = 'general' order by `ct`.`createdAt` desc
This query actually works how I need it to. The only issue is that a row won’t return if the subquery is empty. I still want to return all of the data outside of the subquery even if the subquery is null / false / empty. I've tried using IFNULL / ISNULL, but I don't think I'm using it right with the additional joins in the subquery.
if I have 2 topics, 1 topic with 5 posts, 1 topic with 0 posts, only the topic with 5 posts will show up and the topic with 0 posts won’t show up because the subquery returns empty.
If the row is empty, I’d like to return something to the front end user showing something like “Sorry, no recent posts” or something along those lines.
Any help would be amazing!
You want a left join if you want to keep rows even when there is no match:
select `ct`.*, `a`.`username`, `x`.*
from `community-topics` `ct` inner join
`community-categories` `cc`
on `cc`.`communityCategoryId` = `ct`.`refCategoryId` inner join
`authentication` `a`
on `a`.`userId` = `ct`.`refCreatedBy` left join
(select `a2`.`username` AS lastPostUsername, `cp`.`createdAt` AS lastPostCreatedAt,
`cp`.`body`, `cp`.`refTopicId`
from `community-posts` as `cp` left join
`authentication` as `a2`
on `a2`.`userId` = `cp`.`refCreatedBy`
order by `cp`.`createdAt` desc limit 1
) x
on `x`.`refTopicId` = `ct`.`communityTopicId`
where `cc`.`name` = 'general'
order by `ct`.`createdAt` desc;
I would also recommend that you remove all the backticks. They just make the query harder to write and to read.
EDIT:
If I understand your comment:
select `ct`.*, `a`.`username`, `x`.*
from `community-topics` `ct` inner join
`community-categories` `cc`
on `cc`.`communityCategoryId` = `ct`.`refCategoryId` inner join
`authentication` `a`
on `a`.`userId` = `ct`.`refCreatedBy` left join
(select `a2`.`username` AS lastPostUsername, `cp`.`createdAt` AS lastPostCreatedAt,
`cp`.`body`, `cp`.`refTopicId`,
row_number() over (partition by refTopicId order by cp.created_at desc) as seqnum
from `community-posts` as `cp` left join
`authentication` as `a2`
on `a2`.`userId` = `cp`.`refCreatedBy`
) x
on `x`.`refTopicId` = `ct`.`communityTopicId` and seqnum = 1
where `cc`.`name` = 'general'
order by `ct`.`createdAt` desc;

Get last row in LEFT JOIN

What I am trying to do it with below code, getting all keywords with their positions via LEFT JOIN, it works fine but it shows the first position of each keyword, but I want to show the last position that recorded (by date).
SELECT keyword.id, keyword.title, keyword.date, rank.position FROM keyword
LEFT JOIN rank
ON rank.wordid = keyword.id
GROUP BY keyword.id
ORDER BY keyword.date DESC
How can I do this? Should I use subquery or what? Is there any way to do this without a subquery?
SAMPLE DATA
What I want:
Get 17 instead of 13, I mean last record of position.
Do not use group by for this! You want to filter, so use a where clause. In this case, using a correlated subquery works well:
SELECT k.id, k.title, k.date, r.position
FROM keyword k LEFT JOIN
rank r
ON r.wordid = k.id AND
r.date = (SELECT MAX(r2.date)
FROM rank r2
WHERE r2.wordid = k.id
)
ORDER BY k.date DESC
You can use below query
SELECT keyword.id, keyword.title, keyword.date, rankNew.position FROM keyword LEFT JOIN (
SELECT rank.wordid, rank.position FROM rank ORDER BY rank.id DESC LIMIT 0, 1) AS rankNew ON (rankNew.wordid = keyword.id);
You can get more reference from Retrieving the last record in each group - MySQL

MySQL group by twice and COUNT

Some sql query gives me the following result:
As you can see, it already has GROUP BY.
So what I need? I need to group it again (by treatment_name) and count rows for each group. See more details on screenshot.
Here is full query:
SELECT
treatment_summaries.*
FROM `treatment_summaries`
INNER JOIN
`treatments`
ON
`treatments`.`treatment_summary_id` = `treatment_summaries`.`id`
AND
(treatment <> '' and treatment is not null)
INNER JOIN
`treatment_reviews`
ON
`treatment_reviews`.`treatment_id` = `treatments`.`id`
INNER JOIN
`conditions_treatment_reviews`
ON
`conditions_treatment_reviews`.`treatment_review_id` = `treatment_reviews`.`id`
INNER JOIN
`conditions` ON `conditions`.`id` = `conditions_treatment_reviews`.`condition_id`
INNER JOIN `conditions_treatment_summaries` `conditions_treatment_summaries_join`
ON
`conditions_treatment_summaries_join`.`treatment_summary_id` = `treatment_summaries`.`id`
INNER JOIN `conditions` `conditions_treatment_summaries`
ON `conditions_treatment_summaries`.`id` = `conditions_treatment_summaries_join`.`condition_id`
WHERE
`conditions`.`id` = 9
AND `conditions`.`id` IN (9)
AND (latest_review_id is not null)
GROUP BY
treatment_reviews.id
ORDER BY
treatment_summaries.reviews_count desc
LIMIT 20 OFFSET 0
Maybe there is another issue, cause GROUP BY should not leave same lines (for given column), but anyway you can wrap it like this:
SELECT * FROM ( YOUR_SQL_SELECT_WITH_EVERYTHING ) GROUP BY id
So the result you get will behave as another table and you can do all operations like GROUP BY again.

GROUP BY not sorting properly when using joins

I want to see only one record from the joined table fr_movements with the newest sched_date yet I am always getting the oldedst sched_date. Since the ORDER BY sorts by the sched_date and I am grouping by the people.ID I am getting only one record from fr_movements as expected, just the wrong one.
SELECT `fr_movements`.`ID`, fr_movements_list.movement_type,
fr_movements.sched_date, fr_movements.comp_date, people.firstname, people.lastname
FROM fr_movements
LEFT JOIN people ON people.ID = fr_movements.`people_id`
LEFT JOIN fr_movements_list ON (fr_movements.move_type_id = fr_movements_list.ID)
WHERE fr_movements.org_id = 25 AND fr_movements.move_type_id IN (54,53,52,51,50,55)
GROUP BY people.ID
ORDER BY people.org_name, fr_movements.sched_date ASC
Anybody know how to do this properly?
as #bluefeet mentioned
you are using GROUP BY incorrectly. GROUP BY is supposed to be used with an aggregate function
You need to put all columns after GROUP BY, but it is complicated. I think DISTINCT might help you. like this:
SELECT *
FROM
(
SELECT DISTINCT people.org_name, `fr_movements`.`ID`, fr_movements_list.movement_type,
fr_movements.sched_date, fr_movements.comp_date, people.firstname, people.lastname
FROM fr_movements
LEFT JOIN people ON people.ID = fr_movements.`people_id`
LEFT JOIN fr_movements_list ON (fr_movements.move_type_id = fr_movements_list.ID)
WHERE fr_movements.org_id = 25
AND fr_movements.move_type_id IN (54,53,52,51,50,55)
) x
ORDER BY org_name, sched_date ASC
If not works, would you post your data & schema into sqlfiddle? That makes us happy.

condition LEFT JOIN with DISTINCT

select wyraz_id, count(wyraz_id) as c from worek w
group by wyraz_id order by c desc limit 11
This query gives me back top 11 favourited wyraz_id from table worek.
LEFT JOIN wyraz FROM wyrazy wy WHERE wy.wyraz_id = w.wyraz_id
The problem is, that wyraz_id in this case should apply to DISTINCT results only.
select wyraz_id, count(wyraz_id) as c from worek w
LEFT JOIN wyraz FROM wyrazy wy
WHERE wy.wyraz_id = w.wyraz_id Having distint(wyraz_id)???
group by wyraz_id order by c desc limit 11
I've managed to go around it by doing another query on the go, but seems pointless really if you can do all that with a simple join.
$d = $row['wyraz_id'];
"select wyraz from wyrazy where wyraz_id='{$d}'";
Thank you kindly for any suggestions.