Reputation: 689
Suppose I have a table food
, which I query SELECT name FROM food ORDER BY name
:
| name
|--------
| Apple
| Banana
| Carrot
| Donut
...
I wish to specify that specific items of my choice be pinned to the top (e.g. "Lemon" and then "Carrot"), if they are in the table. Like so:
| name
| -------
| Lemon
| Carrot
| Apple
| Banana
| Donut
...
What kind of SQL query can I use to get this specific sort?
Upvotes: 3
Views: 3086
Reputation: 336
I'd use CTE and go like this:
WITH FoodOrder(name, foodOrder)
AS
(
SELECT name
, foodOrder = CASE name
WHEN 'Lemon' THEN 200
WHEN 'Carrot' THEN 100
ELSE 0
END
FROM food
)
SELECT name
FROM FoodOrder
ORDER BY foodOrder DESC, name
Please note that if you will choose enough spacing between CASE values (0, 100 ,200) you can easily add another prioritized food afterwards if needed without overwriting already existing values.
Upvotes: 0
Reputation: 1680
Chances are, this is going to be RDBMS specific. The one being used is not specified.
MySQL, commonly used, provides a function field(). Good for custom sorts on bounded values.
mysql> create temporary table food as select 'Apple' as food union select 'Banana' union select 'Carrot' union select 'Donut';
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from food;
+--------+
| food |
+--------+
| Apple |
| Banana |
| Carrot |
| Donut |
+--------+
4 rows in set (0.00 sec)
mysql> select * from food order by field (food, 'Carrot', 'Apple', 'Banana', 'Donut');
+--------+
| food |
+--------+
| Carrot |
| Apple |
| Banana |
| Donut |
+--------+
4 rows in set (0.00 sec)
Upvotes: 0
Reputation: 70538
Make a look up table like this:
WITH odering(F, Ord) AS
(
VALUES ('Lemmon', 2),
('Carrot', 1)
)
SELECT name
FROM table t
LEFT JOIN ordering Ord on T.name = Ord.name
ORDER BY COALESCE(Ord.Ord, 0) DESC, Name ASC
Upvotes: 1
Reputation: 20609
You can use a case statement in your order by clause to prioritize items with a certain name.
The following will put Lemon and Carrot in priority order by assigning them the values of 1 and 2 from the case, where all others will get the value 3. Those remaining that were assigned 3 will then be sorted by the second expression in the order by clause, which is just the name column.
SELECT *
FROM food
ORDER BY
CASE name
WHEN 'Lemon' THEN 1
WHEN 'Carrot' THEN 2
ELSE 3
END,
name
Upvotes: 10