tags:

views:

56

answers:

2

If I have 3 columns, X, Y, Z, that are each a number, how can I get each row returned greatest to least, and then the rows return greatest to least?

So if I had:

X    Y    Z
8    7    9
1    2    3
4    6    5

how could I get:

9    8    7
6    5    4
3    2    1
+1  A: 
SELECT CASE WHEN X >= Y && X >= Z THEN X
            WHEN Y >= Z && Y >= X THEN Y
            ELSE Z END,
CASE WHEN X >= Y && X < Z THEN X
     WHEN X >= Z && X < Y THEN X
     WHEN Y >= X && Y < Z THEN Y
     WHEN Y >= Z && Y < Z THEN Y
     ELSE Z END,
CASE WHEN X <= Y && X <= Z THEN X
     WHEN Y <= Z && Y <= X THEN Y
     ELSE Z
FROM Table
ORDER BY CASE WHEN X >= Y && X >= Z THEN X
            WHEN Y >= Z && Y >= X THEN Y
            ELSE Z END;

Off of the top of my head, that should work. I'm not going to make promises on performance. If this were Microsoft SQL, I'd be tempted to make a second table which stored the values per row in order, and have a Trigger set up to keep the second table up to date.

Now, that's pretty obviously only going to work if you have 3 columns. 4 columns is more of a headache, and that's really where you need to start thinking up a new way to store the info, such as a table like this:

------------------------------
| row_id | column_id | value |
------------------------------
|   1    |   'X'     |   7   |
|   1    |   'Y'     |   8   |
|   1    |   'Z'     |   9   |
|   2    |   'X'     |   3   |

... and so forth.

Once you've got the data in this format, doing some sort of:

SELECT row_id, value FROM TABLE ORDER BY row_id, value DESC;

suddenly becomes super-easy.

John Fiala
A: 

You can code for specific numbers of columns, as in John's answer, but you can't easily do this for the general case. If this is a requirement then I'd consider redsigning the schema to support it.

Jim Garrison