Reputation: 15552
Im a bit stuck on an order by column. Ive got some good answers to another query from stack overflow but now just need to order it correctly.
Consider I have these results (unordered)
|LloydA|20|
|LloydB|0 |
|LloydC|5 |
|JonesA|10|
|JonesB|0 |
|ZuberA|0 |
|ZuberB|10|
then want to order them first by column two but also withing it column 1 so the results are
|LloydA|20|
|LloydC|5 |
|LloydB|0 |
|JonesA|10|
|JonesB|0 |
|ZuberB|10|
|ZuberA|0 |
Because the 20 is hte maximum I want to show this row at the top and then show all the ones with the same start of name after it (ie all the Lloyd..)
I'm thinking a subselect with the order by but Im struggling. Has anyone got any tips.
Upvotes: 1
Views: 164
Reputation: 60462
Based on your previous SO question you don't need to extract the name, you simply have to add a GROUP MAX:
-- copied from the accepted answer
select p.* from people p
join (select p1.first_name, p1.last_name
from people p1 where p1.id = 17
)un
on un.first_name = p.first_name
where p.last_name like un.last_name || '%'
-- ADDED
order by -- find the MAX for each name
max(col2) over (partition by un.last_name),
last_name
Upvotes: 1
Reputation: 220877
Here's a query that produces the results that you need:
WITH
-- "t" contains the raw data
t(name, score) AS (
SELECT 'Lloyd0', 20 FROM DUAL UNION ALL
SELECT 'Lloyd1', 0 FROM DUAL UNION ALL
SELECT 'Lloyd2', 5 FROM DUAL UNION ALL
SELECT 'Jones0', 10 FROM DUAL UNION ALL
SELECT 'Jones1', 0 FROM DUAL UNION ALL
SELECT 'Zuber0', 0 FROM DUAL UNION ALL
SELECT 'Zuber1', 10 FROM DUAL
),
-- "u" generates the "name prefix" by removing the numbers form the names
u(name, score, name_prefix) AS (
SELECT name, score, regexp_replace(name, '\d+', '')
FROM t
),
-- "v" generates the max score per name_prefix ("group_rank") for each "group"
v(name, score, group_rank, name_prefix) AS (
SELECT name, score, MAX(score) OVER (PARTITION BY name_prefix), name_prefix
FROM u
)
SELECT name, score
FROM v
ORDER BY
-- Order by the group's rank first
group_rank DESC,
-- Order equally ranked groups by name
name_prefix ASC,
-- Order entries within each group by score
score DESC
Of course, you don't need to use common table expressions for this. This could be done with derived tables, or views as well, or by repeating certain expressions.
Note: Your original question referred to Lloyd0
instead of LloydA
. It isn't quite clear what the "interesting" part of a name really is (e.g. Lloyd
), and what the "non-interesting" part is (e.g. A
or 0
). But I suspect that doesn't really matter for the answer.
Upvotes: 1