Searched through the articles but couldn't find anything specific for solving my problem.
SELECT `id_von`, `message`, `timestamp`
FROM `messages`
WHERE `id_von` = $session_user_id OR `id_re` = $session_user_id
GROUP BY id_von
ORDER BY TIMESTAMP DESC
Problem is it is not the newest entry. Its actually the first one in the DB.
Would really appreciate the help.
It's more comment then answer, but I can't insert formatted code in comment. Possible problem with TIMESTAMP because it data type. Try to use alias:
SELECT m.id_von, m.message, m.timestamp
FROM messages m
WHERE m.id_von = $session_user_id OR m.id_re = $session_user_id
GROUP BY m.id_von
ORDER BY m.TIMESTAMP DESC
Furthermore try to replace ORDER BY m.TIMESTAMP DESC upon ORDER BY 3 DESC
UPD. Using group by meaningful with aggregate function such as sum
Related
I have this:
SELECT FirstName
FROM MAIN_TABLE_LEVEL100
WHERE FirstName IN
(
SELECT DISTINCT FirstName
FROM MAIN_TABLE_LEVEL100
)
ORDER BY `level` DESC, `time` DESC LIMIT 0,10
Im trying to get top 10 diferents names order by level and time, but it doesn't work, if someone can help me please, thanks.
Your where clause is doing nothing, you just repeated the same select that you had above. As long as level and time are in 'MAIN_TABLE_LEVEL100' you don't even need a where clause. This should work:
SELECT DISTINCT FirstName, level, time
FROM MAIN_TABLE_LEVEL100
ORDER BY level DESC, time DESC LIMIT 10
Why don't use GROUP BY .DISTINCT work only with indexed field in some situation.
You can have multiple lines because of time. Try rolling the data together first.
I'm not familiar with mySql, but using generic SQL syntax it would be something like this:
SELECT b.FirstName
FROM (SELECT a.FirstName, a.Level, MAX(a.Time) AS tm FROM MAIN_TABLE_LEVEL100 as a GROUP BY a.FirstName, a.Level) AS b
ORDER By b.Level, b.tm
Thanks everyone, I finally found the right answer!:
SELECT o.FirstName, o.Level, o.Time, o.City
FROM `MAIN_TABLE_LEVEL100` o # 'o' from 'bigger points'
LEFT JOIN `MAIN_TABLE_LEVEL100` b # 'b' from 'bigger after o'
ON o.FirstName = b.FirstName AND o.Points < b.Points
WHERE b.Points is NULL
ORDER BY `o`.`Points` DESC
LIMIT 0,10
thanks everyone, i hope someone need it ;)
I have the below query and it works fine at returning results based on the set timestamp.
SELECT * FROM catalog WHERE part IN (SELECT part FROM query_data WHERE timestamp >= '2015-02-02') LIMIT 10
What I would like to do is get the results from the above but ORDER BY timestamp in DESC order. Something like this, but it doesn't work. The same values are returned, but not in DESC order based on the timestamp.
SELECT * FROM catalog WHERE part IN (SELECT part FROM query_data WHERE timestamp >= '2015-02-02' ORDER BY timestamp DESC) LIMIT 10
Thoughts? The timestamp column is only found in the query_data table. Not sure if this is causing the issue or not?
I believe this will work:
SELECT * FROM catalog c INNER JOIN query_data q ON c.part = q.part WHERE q.timestamp >= '2015-02-02' ORDER BY timestamp DESC;
The main problem with your approach is that you are ordering the subquery. Using a join and "order by" outside should fix it.
I would encourage you to watch this link (subselect order timestamp) The problem you have is as you thought, even if the subselect is ordered then it gets out of place on the main query, a Join would be useful for this cases.
Hope it helps you.
I need to perform a sort before the GROUP BY clause, but MySQL does not want to cooperate.
SELECT `article`, `date`, `aip`
FROM `official_prices`
WHERE `article` = 2003
GROUP BY `article`
ORDER BY `date` ASC
The row that should be picked is the one with the earliest date (2013-07-15) but instead it picks the date that comes first in table order. Changing to DESC does no difference.
First image shows both rows, ungrouped. Second image is them being grouped.
This table is being joined to by a main query, so (I think) any solutions involving LIMIT 1 won't be useful to me.
Full query:
SELECT `articles`.*, `official_prices`.`aip`
FROM `articles`
LEFT JOIN `official_prices`
ON (`official_prices`.`article` = `articles`.`id`)
GROUP BY `articles`.`id`, `official_prices`.`article`
ORDER BY `official_prices`.`date` ASC, `articles`.`name`
You can't use group by and order like that. The order will only apply to the complete record set being returned and not in the group itself. This will work:
select o1.*
from official_prices o1
inner join
(
SELECT `article`, min(`date`) as mdate
from `official_prices`
WHERE `article` = 2003
GROUP BY `article`
) o2 on o1.article = o2.article and o1.date = o2.mdate
What you are trying to do is simply incorrect. The ordering before the group by does not have a (guaranteed) effect on the results.
My guess is that you want to get the most recent date and aip for that date. Here is a better approach:
SELECT `article`, max(`date`),
substring_index(group_concat(`aip` order by date desc), ',', 1) as lastAip
FROM `official_prices`
WHERE `article` = 2003
GROUP BY `article`;
The only downside is that the group_concat() will convert any value to a string. If it is some other type (and a string poses problems), then convert it back to the desired type.
Actually, an even better approach is to skip the group by entirely, because you are already filtering down to one article:
select article, `date`, aip
from official_prices
where article = 2003
order by `date` desc
limit 1;
The first approach works for multiple articles.
EDIT:
Your full query is:
SELECT `articles`.*, `official_prices`.`aip`
FROM `articles` LEFT JOIN
`official_prices`
ON `official_prices`.`article` = `articles`.`id`
GROUP BY `articles`.`id`, `official_prices`.`article`
ORDER BY `official_prices`.`date` ASC, `articles`.`name`;
You are looking for more than one article, so the second approach won't work. So, use the first:
SELECT `articles`.*,
substring_index(group_concat(`official_prices`.`aip` order by `official_prices`.`date` desc),
',', 1) as lastAIP
FROM `articles` LEFT JOIN
`official_prices`
ON `official_prices`.`article` = `articles`.`id`
GROUP BY `articles`.`id`, `official_prices`.`article`
ORDER BY `articles`.`name`;
I am struggling to find the right answer looking around the internet for how to do this, I have a join and a group. When I add a Limit to the end it limits the groups and not the actual results.
SELECT COUNT(*) AS `numrows`, `people`.`age`
FROM (`events`)
JOIN `people`
ON `events`.`id` = `people`.`id`
WHERE `people`.`priority` = '1'
GROUP BY `people`.`age`
ORDER BY `numrows`
LIMIT 150
The limit always changes so this needs to be dynamic, the idea is to miss out the first 150 or x amount of rows from both tables but not the to limit the groups.
EDIT= I think I have explained this badly, I actually want to start from 150 rows or x, limit is the only way I know to do this dynamically. so the idea is if the last search was retrieved 150 rows, then lets say next time there are 250 results but I want to ignore the first 150 which were found last time etc.. Hope that makes better sense.
there limit or start from needs to be after the WHERE in the join, I think that's the only place it would work.
EDIT SQL =
SELECT COUNT( * ) AS `numrows`, `people`.`age`
FROM (
SELECT `id`, `events`.`pid`
FROM `events`
ORDER BY `id`
LIMIT 1050
)limited
JOIN `people` ON `people`.`age` = limited.id
WHERE `people`.`priority` = '1'
GROUP BY `people`.`age`
ORDER BY `numrows` DESC
Thanks for your help
I suspect you mean something like this?
SELECT COUNT(*) AS numrows, people.age
FROM (
SELECT id FROM events ORDER BY id LIMIT 150
) limited
JOIN people ON people.id = limited.id
GROUP BY people.age
ORDER BY numrows;
I did it using where between on timestamp, it seems like the only sensible way to do it.
I have tried to program a inbox that display messages in the order they were received and then by if they have been read or not, it seemed to work for a while, but not it doesn't. It may have only worked under certain circumstances maybe..
Anyway here is my query;
SELECT `id`, `from_userid`, `read`, max(sent) AS sent
FROM (`who_messages`)
WHERE `to_userid` = '41'
GROUP BY `from_userid`
ORDER BY `read` ASC, `sent` DESC
I believe the problem is that the messages are being grouped in the wrong order.. as the inbox is always showing as read, when new messages exist. I get the right time of the new messages, but I am guessing this because I selected max(sent).
Is my logic wrong? or can I sort and then group as all my efforts have resulted in 'Every derived table must have its own alias'
Setup an SQL Fiddle - here's the best I came up with. Basically I do the ordering first in a sub-query then group them afterwards. That seemed to work with the (limited) test data I entered.
SELECT *
FROM (SELECT id, from_userid, is_read, sent
FROM who_messages
WHERE to_userid = 41
ORDER BY from_userid ASC, is_read ASC) m
GROUP BY m.from_userid
ORDER BY m.is_read ASC, m.sent DESC
See the fiddle to play around: http://sqlfiddle.com/#!2/4f63d/8
You are selecting non-grouping fields in a grouped query. It is not guaranteed which record of the group will be returned, and ORDER BY is processed after GROUP BY.
Try this:
SELECT m.*
FROM (
SELECT DISTINCT from_userid
FROM who_messages
WHERE to_userid = 41
) md
JOIN who_messages m
ON m.id =
(
SELECT mi.id
FROM who_message mi
WHERE (mi.to_userid, mi.from_userid) = (41, md.from_userid)
ORDER BY
mi.sent DESC, mi.id DESC
LIMIT 1
)
Create an index on who_message (to_userid, from_userid, sent, id) for this to work fast.
Update
The above query will return the record for the last message from any given user (including its read status). If you want to check that you have any unread messages from the user, use this:
SELECT m.*, md.all_read
FROM (
SELECT from_userid, MIN(read) AS all_read
FROM who_messages
WHERE to_userid = 41
GROUP BY
from_userid
) md
JOIN who_messages m
ON m.id =
(
SELECT mi.id
FROM who_message mi
WHERE (mi.to_userid, mi.from_userid) = (41, md.from_userid)
ORDER BY
mi.sent DESC, mi.id DESC
LIMIT 1
)
For this to work fast, create an index on who_message (to_userid, from_userid, read) (in addition to the previous index).
As Quassnoi said, you are using a GROUP BY query and ordering on 'read' which is not an aggregate function. Therefore you can't be certain of the value used by the MySQL engine (usually the last of the group but...)
I would suggest writing your query this way, as it doesn't involve any subquery and has some many other performance-friendly usage:
SELECT
from_userid,
COUNT(*) AS nb_messages,
SUM(NOT is_read) AS nb_unread_messages,
MAX(sent) AS last_sent
FROM who_messages
WHERE to_userid = 41
GROUP BY from_userid
ORDER BY nb_unread_messages DESC, last_sent DESC;
(I used Andy Jones' fiddle schema: http://sqlfiddle.com/#!2/4f63d/8.
By the way, many thanks Andy, this site is great !)
Hope this help !
"inbox that display messages in the order they were received and then by if they have been read or not ... however it is suppose to be the latest message" - assumes read is a nullable date/time column, and messages are stored in the order they are sent (newer have larger id than older - autoid)
SELECT wm.id, wm.from_userid, (wm.read IS NULL) as unread, wm.sent
FROM (SELECT MAX(id) AS id FROM who_messages WHERE to_userid = '41' GROUP BY from_userid) sub
INNER JOIN who_messages wm ON sub.id = wm.id
ORDER BY wm.sent DESC, wm.read