1

I have a query like this:

(SELECT * FROM something WHERE ...) UNION (SELECT * FROM something WHERE ...)

Because I want the results from the first SELECT to come out on top. But, the second part comes out in reverse order. I can't simply order the entire query because it will push the first SELECT that I need at the top to the bottom... So I want to do something like this:

(SELECT * FROM something WHERE ...) UNION (SELECT * FROM something WHERE ...  ORDER BY timestamp DESC)

But this just doesn't work, the ORDER BY is completely ignored; I tested this by inserting gibberish, ORDER BY dosaif30h still works... One solution would be to make two separate queries, but I'd much prefer to handle it in one.

Christopher Reid
  • 4,318
  • 3
  • 35
  • 74

3 Answers3

3
SELECT * FROM something WHERE ... UNION SELECT * FROM (SELECT * FROM something WHERE ...  ORDER BY timestamp DESC)a
Shahar
  • 1,687
  • 2
  • 12
  • 18
  • without the a on the end I got `OperationalError: (1248, 'Every derived table must have its own alias')` and with it... `Syntax Error` – Christopher Reid Jan 14 '15 at 02:26
  • @AllTheTime Note the `a` I added at the end. That's the alias that you must have. Add that. – Shahar Jan 14 '15 at 02:26
  • Your answer is super close and it got me to this... which works. Edit your answer and I will accept. `(SELECT * FROM something WHERE ...) UNION ( SELECT * FROM (SELECT * FROM something WHERE ... ORDER BY timestamp DESC) as a )` – Christopher Reid Jan 14 '15 at 02:28
  • @AllTheTime Try doing what I did in my answer, that should work as well (that's how I do it). Actually, it's equivalent to what you have, except less characters (better readability?). – Shahar Jan 14 '15 at 02:30
  • strange. Must be the version / engine I'm using (MySQLdb for python) It only works for me with the brackets and verbosity displayed in the above comment. – Christopher Reid Jan 14 '15 at 02:33
  • @AllTheTime Oh I found the mistake. The first statement shouldn't have had the parentheses. Try it now. – Shahar Jan 14 '15 at 02:38
  • 1
    This answer is not correct. There is no guarantee that the results of a `union` will be in the order of the query or that the ordering in a subquery is respected. In most cases, the only way to guarantee the ordering of a query is to use an `order by` at the outermost level. – Gordon Linoff Jan 14 '15 at 03:28
1

If you want to order both of them in one order, then you need something like this:

SELECT * FROM (
    SELECT * FROM table_1 where something
    UNION
    SELECT * FROM table_2 WHERE something
) as tt
ORDER BY something

Note that both tables should have same column names and count.

If you want to order only the second query then:

SELECT * FROM table_1 where something
        UNION
SELECT * FROM (SELECT * FROM table_2 WHERE something ORDER BY something) as tt
bksi
  • 1,606
  • 1
  • 23
  • 45
1

If you want the first table to come first, then you need to order by that explicitly:

SELECT s.*
FROM ((SELECT s.*, 1 as which FROM something s WHERE ...)
      UNION ALL
      (SELECT s.*, 2 as which FROM something s WHERE ...)
     ) s
ORDER BY which, timestamp DESC

You can only trust an order by in the outer query -- in most circumstances -- if you want the results in a particular order.

NOTE: You can write this without the subquery if you like:

SELECT s.*, 1 as which FROM something s WHERE ...
UNION ALL
SELECT s.*, 2 as which FROM something s WHERE ...
ORDER BY which, timestamp;
Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786