Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom MySQL Ordering

Tags:

sql

php

mysql

I have a query that needs a custom sorting, trimmed down to the bare minimums something like:

SELECT u.*, p.*, p.id as product_id
FROM users u, products p 
WHERE u.id = p.user_id
ORDER BY product_id DESC

And I get returned a set of rows like:

UserID        ProductID
     2                5
     2                4
     3                3
     1                2
     1                1

But I want it to actually sort SOMETHING like this (so no 2 UserIDs are adjacent to eachother):

 UserID        ProductID
     1                2
     2                4
     3                3
     2                5
     1                1

Is this even possible with MySQL, or do I need some PHP magic?

like image 531
Adam Skiba Avatar asked May 31 '13 05:05

Adam Skiba


People also ask

How do I create a custom order in SQL?

By default SQL ORDER BY sort, the column in ascending order but when the descending order is needed ORDER BY DESC can be used. In case when we need a custom sort then we need to use a CASE statement where we have to mention the priorities to get the column sorted.

How do I change the order of rows in MySQL?

An "ALTER TABLE ORDER BY" statement exist in the syntaxes accepted by MySQL. According to the documentation, this syntax: - only accept *one* column, as in "ALTER TABLE t ORDER BY col;" - is used to reorder physically the rows in a table, for optimizations.

How does MySQL ORDER BY?

The MySQL ORDER BY Keyword The ORDER BY keyword is used to sort the result-set in ascending or descending order. The ORDER BY keyword sorts the records in ascending order by default. To sort the records in descending order, use the DESC keyword.

How do you ORDER BY field?

select type , COUNT from TABLE order by FIELD(type,'A','B','C','D') ; It works fine if the column type has value for 'A,B,C,D' . In some cases the order by FIELD('A','B','C','D') some columns may not have value in table . In this cases I want to put 0 for it and construct a result .


Video Answer


1 Answers

A canonical way of solving this problem is by enumerating the duplicate rows and then ordering by that value:

select t.*
from (SELECT u.*, p.*, p.id as product_id,
             row_number() over (partition by u.id order by (select NULL)) as seqnum
      FROM users u join
           products p 
           on u.id = p.user_id
     ) t
order by seqnum, id;

This will work, as long as no one user has a really long sequence (as in your example).

There is no "always-works" solution, because it is easy to come up with a situation where your goal is not possible.

like image 153
Gordon Linoff Avatar answered Oct 06 '22 01:10

Gordon Linoff