tags:

views:

1108

answers:

4

I've got a table, called faq_questions with the following structure:

id int not_null auto_increment,
question varchar(255),
sort_order int

I'm attempting to build a query that given a sort order, selects the row with the next highest sort order.

Example:

id  question                sort_order
1   'This is question 1'    10
2   'This is question 2'    9
3   'This is another'       8
4   'This is another one'   5
5   'This is yet another'   4

Ok, so imagine I pass in 5 for my known sort order (id 4), I need it to return the row with id 3. Since there's no guarantee that sort_order will be contiguous I can't just select known_sort_order + 1.

Thanks!

+3  A: 

It seems too simple, but it looks like what you need:

SELECT id,question FROM `questions` 
WHERE `sort_order` > sort_order_variable
ORDER BY sort_order ASC 
LIMIT 1
Eran Galperin
Be sure to ORDER BY sort_order DESC otherwise you will get weird results
Matt Rogish
ASC, since he wants the next lowest entry
Eran Galperin
Whoops, I saw ID = 3 and thought he meant sort_order =3 . You got it :D
Matt Rogish
That should be >, not <.
Bill Karwin
And there's no reason to put quotes around the sort order variable if it's an integer (and it might interfere with the optimizer).
Bill Karwin
< since he wants the next lowest (3 < 5)
Eran Galperin
It *will* interfere with the optimizer, from my personal experience.
le dorfier
@Eran: He wants the row with sort_order = 8, not 3.
Bill Karwin
You're right... he confused me with the id numbering in his question. Fixed
Eran Galperin
+1  A: 

You can do it with TOP or LIMIT:

SELECT TOP 1 * FROM faq_questions WHERE sort_order > 5 ORDER BY sort_order ASC

but that's not as elegant or portable as

SELECT *
FROM faq_questions AS f1
LEFT JOIN faq_questions AS f2
ON f1.sort_order > f2.sort_order
AND f2.sort_order = 5
LEFT JOIN faq_questions AS f3
ON f3.sort_order BETWEEN f1.sort_order AND f2.sort_order
WHERE f3.id IS NULL

le dorfier
"TOP N" is a nonstandard Microsoft/Sybase feature. MySQL does not support it.
Bill Karwin
Right, that's why I put LIMIT (since I didn't notice the title, the only place where MySQL was identified.) :) Is LIMIT an SQL standard?
le dorfier
No, LIMIT is nonstandard SQL. As far as I know, it's supported only by MySQL/PostgreSQL/SQLite.
Bill Karwin
That's what I thought - any record-count limit is non-standard (which Codd and Date would appreciate, I imagine.) So my "portable" assertion is ok. :)
le dorfier
A: 
SELECT 
    id, question, sort_order
FROM faq_questions 
WHERE sort_order in 
(SELECT 
        MIN(sort_order) 
    FROM faq_questions 
    WHERE sort_order > ?);

That seems to work

Electronic Zebra
Yes, that works. You can also use = instead of IN, since the subquery returns a single value.
Bill Karwin
Thanks, my brain seems to be broken today, haha
Electronic Zebra
+1  A: 
SELECT * FROM table_name WHERE sort_order > 5 ORDER BY sort_order ASC LIMIT 1
alexeit