Ordering by the order of values in a SQL IN() clause

前端 未结 13 787
旧巷少年郎
旧巷少年郎 2020-11-22 04:12

I am wondering if there is away (possibly a better way) to order by the order of the values in an IN() clause.

The problem is that I have 2 queries, one that gets al

相关标签:
13条回答
  • 2020-11-22 04:44

    Use MySQL's FIELD() function:

    SELECT name, description, ...
    FROM ...
    WHERE id IN([ids, any order])
    ORDER BY FIELD(id, [ids in order])
    

    FIELD() will return the index of the first parameter that is equal to the first parameter (other than the first parameter itself).

    FIELD('a', 'a', 'b', 'c')

    will return 1

    FIELD('a', 'c', 'b', 'a')

    will return 3

    This will do exactly what you want if you paste the ids into the IN() clause and the FIELD() function in the same order.

    0 讨论(0)
  • 2020-11-22 04:44

    I think you should manage to store your data in a way that you will simply do a join and it will be perfect, so no hacks and complicated things going on.

    I have for instance a "Recently played" list of track ids, on SQLite i simply do:

    SELECT * FROM recently NATURAL JOIN tracks;
    
    0 讨论(0)
  • 2020-11-22 04:47

    For Oracle, John's solution using instr() function works. Here's slightly different solution that worked - SELECT id FROM table1 WHERE id IN (1, 20, 45, 60) ORDER BY instr('1, 20, 45, 60', id)

    0 讨论(0)
  • 2020-11-22 04:49

    My first thought was to write a single query, but you said that was not possible because one is run by the user and the other is run in the background. How are you storing the list of ids to pass from the user to the background process? Why not put them in a temporary table with a column to signify the order.

    So how about this:

    1. The user interface bit runs and inserts values into a new table you create. It would insert the id, position and some sort of job number identifier)
    2. The job number is passed to the background process (instead of all the ids)
    3. The background process does a select from the table in step 1 and you join in to get the other information that you require. It uses the job number in the WHERE clause and orders by the position column.
    4. The background process, when finished, deletes from the table based on the job identifier.
    0 讨论(0)
  • 2020-11-22 04:53

    Ans to get sorted data.

    SELECT ...
    FROM ...
    ORDER  BY FIELD(user_id,5,3,2,...,50)  LIMIT 10
    
    0 讨论(0)
  • 2020-11-22 04:56

    If you want to do arbitrary sorting on a query using values inputted by the query in MS SQL Server 2008+, it can be done by creating a table on the fly and doing a join like so (using nomenclature from OP).

    SELECT table1.name, table1.description ... 
    FROM (VALUES (id1,1), (id2,2), (id3,3) ...) AS orderTbl(orderKey, orderIdx) 
    LEFT JOIN table1 ON orderTbl.orderKey=table1.id
    ORDER BY orderTbl.orderIdx
    

    If you replace the VALUES statement with something else that does the same thing, but in ANSI SQL, then this should work on any SQL database.

    Note: The second column in the created table (orderTbl.orderIdx) is necessary when querying record sets larger than 100 or so. I originally didn't have an orderIdx column, but found that with result sets larger than 100 I had to explicitly sort by that column; in SQL Server Express 2014 anyways.

    0 讨论(0)
提交回复
热议问题