Reputation: 1941
Situation:
At the moment I have 3 queries:
I want to have only 1 Query which could take "needed one" by id + previous and next ones if they exists.
Queries:
First
set @position = 0;
SELECT
`position` FROM
(
SELECT `id`, @position:=@position+1 as `position` FROM {#table}
"other_part_of_query"
ORDER BY `modified_time` DESC
) t
WHERE
t.id = '".id."'
LIMIT 1
Second and third
set @position = 0;
SELECT
`id` FROM
(
SELECT `id`, @position:=@position+1 as `position` FROM {#table}
"other_part_of_query"
ORDER BY `modified_time` DESC
) t
WHERE
t.`position` = '".position."'
LIMIT 1
Upvotes: 2
Views: 98
Reputation: 1234
Selecting next and previous rows of a specific row
SET @j = 0;
SET @i = 0;
SELECT *
FROM (
SELECT id, col1, col2, ..., @j:=@j+1 AS pos
FROM `table`
WHERE col1=... ORDER BY col1 DESC, col2 ASC
) AS zz
WHERE (
SELECT position
FROM (
SELECT id AS id2, @i:=@i+1 AS position
FROM `table`
WHERE col1=... ORDER BY col1 DESC, col2 ASC
) AS zz
WHERE id2=$currId
)
IN (pos-1, pos, pos+1)
Upvotes: 0
Reputation: 1269773
This is complicated, because you are selecting a row by id
, but choosing the adjacent ones by another field, modified_time
.
The idea is to use variables to enumerate the rows. And, use another row to calculate the value for the id
that you care about. Do this in a subquery, and then select the rows that you want:
SELECT t.*
FROM (SELECT `id`,
@rn := if(@rnid := if(t.id = '".id."', @rn + 1, @rnid),
@rn + 1, @rn + 1
) as rn
FROM {#table} t
"other_part_of_query" cross join
(select @rn := 0, @rnid := 0) vars
ORDER BY `modified_time` DESC
) t
WHERE rn in (@rnid - 1, @rnid, @rn)
Upvotes: 1
Reputation: 16691
You can use extra conditions in your where clause to solve this. Consider the following three conditions:
Try this:
SELECT *
FROM myTable
WHERE modified_time = @myParam
OR modified_time = (SELECT MAX(modified_time ) FROM myTable WHERE modified_time < @myParam)
OR modified_time = (SELECT MIN(modified_time ) FROM myTable WHERE modified_time > @myParam);
Upvotes: 0