I want to get recent messages of user. And I need get LAST ID of message to each a fetch. How can I do it? Thank you!
Structure:
Query:
SELECT *
FROM `messages`
WHERE (
`from` = 1 OR
`to` = 1
)
GROUP BY (`from` + `to`)
ORDER BY `id` DESC
LIMIT 10
Result:
What I need?
If you have same a problem? I find solution!
SELECT `id`, `from`, `to`, `text`, `created`
FROM (
SELECT *, (`from` + `to`) AS `anchor`
FROM `messages`
WHERE (
`from` = 1 OR
`to` = 1
)
ORDER BY `id` DESC
LIMIT 1
) AS `*`
GROUP BY `anchor`;
If I understand correctly, you can use a correlated subquery:
select m.*
from messages m
where 1 in (m.from, m.to) and
m.id = (select max(m2.id)
from messages m2
where (m2.from = m.from and m2.to = m.to) or
(m2.from = m.to and m2.to = m.from)
);
Note: from and to are really bad names for columns, because they are SQL keywords.
Related
SELECT
student.Student_Name
FROM
`student`
GROUP BY
student.Student_ID,
teacher.Department_No IN (
SELECT
teacher.Department_No
FROM
`teacher`, `building`
WHERE
teacher.Department_No BETWEEN 1000
AND 2999
GROUP BY
teacher.Department_No = (
SELECT
*
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
)
) LIMIT 0, 25
Your sql has two issues:
You need to use IN instead of = OR limit the subquery to only one record
You need to use a specify column instead of * in the subquery
use IN
teacher.Department_No IN (
SELECT
Department_No
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
)
use LIMIT
teacher.Department_No = (
SELECT
Department_No
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
LIMIT 1
)
You need to select one column like deparment_id in subquery part
SELECT
student.Student_Name
FROM
`student`
GROUP BY
student.Student_ID,
teacher.Department_No IN (
SELECT
teacher.Department_No
FROM
`teacher`, `building`
WHERE
teacher.Department_No BETWEEN 1000
AND 2999
GROUP BY
teacher.Department_No = (
SELECT
department_id
FROM
`building`
WHERE
building.Building_No IN ( '1', '2')
)
) LIMIT 0, 25
MySQL delete statement based on sub-select with multiple return values.
Here is what I am doing now:
DELETE FROM `dnsstats` WHERE id NOT IN
(
SELECT id FROM
(
SELECT id FROM `dnsstats` WHERE peerhost = 'x.x.x.243' ORDER BY id DESC LIMIT 500
) foo
)
AND id NOT IN
(
SELECT id FROM
(
SELECT id FROM `dnsstats` WHERE peerhost = 'x.x.x.40' ORDER BY id DESC LIMIT 500
) foo2
)
AND id NOT IN
(
SELECT id FROM
(
SELECT id FROM `dnsstats` WHERE peerhost = 'x.x.x.50' ORDER BY id DESC LIMIT 500
) foo3
);
This works great, but I would like to select the individual IP addresses dynamically like so:
SELECT peerhost FROM `dnsstats` GROUP BY peerhost;
..and delete based on those returned values.
This is what i tried (and failed):
DELETE FROM `dnsstats` WHERE id NOT IN
(
SELECT id FROM
(
SELECT id FROM `dnsstats` WHERE peerhost = (
SELECT peerhost FROM `dnsstats` GROUP BY peerhost;
) ORDER BY id DESC LIMIT 500
) foo
);
Any idea what I can do to make this work? Thanks!
I think you might need to remove the semicolon in
SELECT peerhost FROM dnsstats GROUP BY peerhost;
The query will run but I don't think you'll get the correct result:
Earlier you were getting 500 from each id related to a peerhost,
now you'll be getting total 500 for all. You need to change the query.
==> Edit: Try this Bryan
DELETE FROM dnsstats WHERE id IN
(
SELECT e.id FROM
(
SELECT d.id FROM dnsstats d
LEFT JOIN
(
SELECT a.peerhost,
(SELECT id FROM dnsstats WHERE peerhost = a.peerhost
ORDER BY id DESC LIMIT 499,1) id
FROM
(SELECT peerhost FROM dnsstats GROUP BY peerhost) a
) c
ON d.peerhost = c.peerhost
WHERE d.id < c.id) e);
That is what you want?
DELETE FROM `dnsstats` WHERE id NOT IN
(
SELECT id FROM
(
SELECT id FROM `dnsstats` WHERE peerhost in (
SELECT peerhost FROM `dnsstats` GROUP BY peerhost;
) ORDER BY id DESC LIMIT 500
) foo
);
Friends i'm using two queries with same concept in the below query i've used two order by function instead i would like to write only one order by function for the whole query using same attribute date_time DESC is it possible in mysql
(SELECT * FROM `chats` WHERE `chat_from` = '18' AND `chat_to` = '13' ORDER BY `date_time` DESC )
UNION
(SELECT * FROM `chats` WHERE `chat_from` = '13' AND `chat_to` = '18' ORDER BY `date_time` DESC )
Try This
SELECT * FROM `chats`
WHERE `chat_from` IN(18,13)
AND `chat_to`IN(18,13)
ORDER BY `date_time` DESC
select * from
(
SELECT * FROM `chats` WHERE `chat_from`in ('18','13') and `chat_to` in ('18','13')
)
t1 ORDER BY `date_time` DESC
You could do something like this:
SELECT * FROM `chats`
WHERE
(
`chat_from` = '18'
AND `chat_to` = '13'
)
OR
(
`chat_from` = '13'
AND `chat_to` = '18'
)
ORDER BY `date_time` DESC
If you need them to be distinct then you can use:
SELECT DISTINCT * FROM `chats`...
I've single chat table as shown in the image. I want to group the chat listing like in facebook style.
Here user 2 is logged in and his conversations are selected using
SELECT *
FROM `chat` `t`
WHERE `from` =2
OR `to` =2
ORDER BY sent DESC
But here I want the latest single entry between 2 and any other user. Where 2 can be in either from or to column. As a final result it should return 2 entries with id 25 and 17 respectively.
SELECT * , (
r.from + r.to
) AS dist
FROM (
SELECT *
FROM `cometchat` t
WHERE (
t.from =2
OR t.to =2
)
ORDER BY t.sent DESC
)r
GROUP BY dist
ORDER BY r.sent DESC
Try this
SELECT *
FROM `chat` `t`
WHERE id IN (SELECT MAX(s.id) FROM chat s WHERE s.`from` =2
OR s.`to` =2 GROUP BY (IF(s.`from`=2, s.`to`, s.`from`)))
ORDER BY sent DESC
I want to select all rows where WHERE (uid = {$uid} OR uid = **HERE** ) where **HERE** is the cids retreived from query 2 below.
Query 1:
SELECT * FROM `t_activities`
WHERE (`uid` = {$uid} OR `uid` = **HERE** )
AND `del` = 0
GROUP BY `fid`
ORDER BY `time` DESC
LIMIT 10
And Query 2:
SELECT `cid` FROM `t_con` WHERE `uid` = {$uid} AND `flag` = 1
SELECT * FROM `t_activities`
WHERE (`uid` = {$uid} OR `uid` in (SELECT `cid`
FROM `t_con`
WHERE `uid` = {$uid} AND `flag` = 1))
AND `del` = 0
GROUP BY `fid`
ORDER BY `time` DESC
LIMIT 10
You can do this as a join as well:
SELECT *
FROM `t_activities` ta left outer join
(SELECT `cid`
FROM `t_con`
WHERE `uid` = {$uid} AND `flag` = 1)
) tc
on ta = tc.cid
WHERE (`uid` = {$uid} OR tc.`uid` is not null) AND `del` = 0
GROUP BY `fid`
ORDER BY `time` DESC
LIMIT 10
By the way, as a SQL statement the "GROUP BY fid" looks very strange. This is allowed in mysql, but I think it is a bad practice. It is much better to be explicit about what you are doing:
SELECT fid, min(<field1>) as Field1, . . .
This helps prevent mistakes when you go back to the query or try to modify it.