Reputation: 231
Let's say you have a table with a integer primary key named 'table_id'
Is it possible in a single query to extract the row with a specific id AND the X row before it AND the X row after it ?
For exemple, if your ids are (1,2,8,12,16,120,250,354), X is 2 and the id you have is 16, the select should return rows with ids 8,12,16,120,250
i know how to do it with several queries, I'm wondering about doing that in a single pass (sub queries, union and all are fine).
Thanks for any help
Upvotes: 5
Views: 1067
Reputation: 14832
Try the following: Unfortunately, I don't have MySQL, but the MS SQL Server version works.
SELECT /*TOP (2*2 +1) --MS SQL Server syntax */
*
FROM IDTable
WHERE IDCol >= (
SELECT MIN(IDCol)
FROM (
SELECT /*TOP 2 --MS SQL Server syntax */
IDCol
FROM IDTable
WHERE IDCol < 16
ORDER BY IDCol DESC limit 2
) t
)
ORDER BY IDCol limit (2*2 +1)
Upvotes: 0
Reputation: 3308
Here's how I would do it, it's simple and it works for signed/unsigned numbers:
-- Finds the closest 5 productID's to 200
SELECT productID, abs(productID - 200) as diff
FROM products
WHERE productID != 200
ORDER BY diff, productID
LIMIT 5
If you're using unsigned numbers, then you'll need to cast the column first:
-- Finds the closest 5 productID's to 200 (unsigned)
SELECT productID, abs(CAST(productID as SIGNED) - 200) as diff
FROM products
WHERE productID != 200
ORDER BY diff, productID
LIMIT 5
Upvotes: 0
Reputation: 484
This works in SQL Server using a derived query:
DECLARE @X int, @target_id int
SET @X = 2
SET @target_id = 8
SELECT [table_id]
FROM
(SELECT TOP ((@X * 2) + 1) [table_id]
,ABS(@target_id - [table_id]) AS [Diff]
FROM [tblItems]
ORDER BY [Diff] ASC) T
ORDER BY table_id ASC
GO
Upvotes: 0
Reputation: 36640
try this:
select table_id from table where id > 16 order by table_id desc limit 2
union all
select table_id from table where id <= 16 order by table_id asc limit 3;
Upvotes: 4
Reputation: 700352
You can make a union between the items before and the item and the items after, but you have to make them subqueries to order them:
select * from (
select * from thetable where table_id >= 16 order by table_id limit 3
) x
union all
select * from (
select * from thetable where table_id < 16 order by table_id desc limit 2
) y
order by table_id
Upvotes: 5
Reputation: 124778
Using MySQL's LIMIT syntax and UNION:
SELECT table_id FROM table WHERE id > 16 ORDER BY table_id ASC LIMIT 2
UNION
SELECT table_id FROM table WHERE id <= 16 ORDER BY table_id DESC LIMIT 3
Upvotes: 0