Reputation: 531
I am having a hard time creating a MySql query that will search a table, row by row and after that return 5 of the surrounding rows on each side.
The problem is that the rows are arranged alphabetically and we can't use the id field
Basically the point is to get 11 rows with the current one exactly in the middle while they are arranged alphabetically.
Upvotes: 1
Views: 189
Reputation: 1269633
This is really easy with union
. Try this:
(select t.* from t where t.col <= YOURNAME
order by t.col desc
limit 6
)
union all
(select t.* from t where t.col > YOURNAME
order by t.col
limit 5
)
order by t.col
The first part of the query returns the five before. The second returns the five after.
By the way, if you have duplicates, you might want this instead:
(select t.* from t where t.col = YOURNAME)
union all
(select t.* from t where t.col < YOURNAME
order by t.col desc
limit 5
)
union all
(select t.* from t where t.col > YOURNAME
order by t.col
limit 5
)
order by t.col
Upvotes: 1
Reputation: 19101
You can solve it with a temp table if you dont have too many records in your table:
create temporary table temp_yourtable(
id int auto_increment,
....,
primary key(id)
)
select ... from yourtable;
select t.* from temp_yourtable t, temp_yourtable t1
where t1.thealpabeticcolumn = your_key and t.id between t1.id - 5 and t1.id + 5
Upvotes: 1
Reputation: 6534
So you want to select a range of rows, row_number should be your friend as you say you can't rely on the id. Check this widely accepted and detailed SO answer about the use of mySQL ROW_NUMBER
.
Then try this working SQL Fiddle code. But I'm still tuning it a bit as it does recover the amount of rows you need by setting up the values on the WHERE tt.row_number between 3 and 7
line but those lines are not around a row selected by you somehow. Tricky thing.
Test data:
id col1
1 adfg
2 sg5r
3 34tdfgdf
4 ergdfd
5 ghjghghj
6 4gfhfrgfr
7 zxcxvfdf
8 sfdgd
9 s8545454
10 7jhgdfe45
11 fbvmso
12 sdfg9dj3
13 zjvjude89
14 _sdfdi3
The query:
SELECT Table1.*
FROM Table1
WHERE col1 IN (
SELECT col1
FROM (SELECT t.col1,
@curRow := @curRow + 1 AS row_number
FROM Table1 t
JOIN (SELECT @curRow := 0) r
) tt
WHERE tt.row_number between 3 and 7
)
ORDER BY col1;
Result data:
ID COL1
3 34tdfgdf
6 4gfhfrgfr
4 ergdfd
5 ghjghghj
7 zxcxvfdf
Upvotes: 1
Reputation: 2302
Try like below, based on your parameters:
SELECT * FROM table WHERE id < 5 LIMIT 10
UNION
SELECT * FROM table WHERE id = 5
UNION
SELECT * FROM table WHERE id > 5 LIMIT 10;
Upvotes: -1