I have a database whose columns are npID, title, URL, and issue.
Here is an example of two years\' entries:
npID title UR
You could make the sub string part of the data being selected
SELECT npId, title, URL, issue, SUBSTRING(issue, 4) AS strsort FROM tbl ORDER BY strsort, issue
Try this approach (this is in T-SQL):
select
*
from
your_table as t
order by
substring([issue], 1, 4) desc,
case substring([issue], 6, len([issue]) - 5)
when 'First_Quarter' then 1
when 'Second_Quarter' then 2
when 'Third_Quarter' then 3
when 'Fourth_quarter' then 4
when 'Spring' then 3
when 'Summer' then 2
when 'Fall' then 4
when 'Winter' then 1
else 5 -- show unexpected input last
end asc
SELECT Column1, row_number() over(order by substring(column2,280,9))
FROM YourTable
This will give the order by
of substring column2.
You can put a CASE
statement in the ORDER BY
to accomplish this. A better route would be to change the application and table to actually store this relevant data in columns where it belongs when you have the development time to do that.
ORDER BY
CAST(SUBSTRING(issue, 1, 4) AS INT) DESC, -- Year
CASE
WHEN issue LIKE '%First_Quarter' OR issue LIKE '%Winter' THEN 1
WHEN issue LIKE '%Second_Quarter' OR issue LIKE '%Spring' THEN 2
WHEN issue LIKE '%Third_Quarter' OR issue LIKE '%Summer' THEN 3
WHEN issue LIKE '%Fourth_Quarter' OR issue LIKE '%Fall' THEN 4
END
Order the seasons however you want. You could also order them in a specific way (Q1 followed by Spring, followed by Q2, etc.) by adjusting the CASE
statement.
Here's a variation of the same theme
ORDER BY
SUBSTRING(issue,1,4) Desc,
CASE SUBSTRING(issue,6, LEN(issue) - 5)
WHEN 'First_Quarter' THEN 1
WHEN 'Second_Quarter' THEN 2
WHEN 'Second_Quarter' THEN 3
WHEN 'Winter' then 1
WHEN 'Spring' then 2
WHEN 'Summer' then 3
WHEN 'Fall' then 4
END
Try a CASE statement in the ORDER BY
:
SELECT npID, title, URL, issue
FROM tbl
ORDER BY substring(issue, 1, 4) DESC
,CASE
WHEN substring(issue, 6, 100) IN ('Winter','First_Quarter') THEN 1
WHEN substring(issue, 6, 100) IN ('Summer','Second_Quarter') THEN 2
WHEN substring(issue, 6, 100) IN ('Spring','Third_Quarter') THEN 3
WHEN substring(issue, 6, 100) IN ('Fall', 'Fourth Quarter') THEN 4
ELSE 5
END;
Don't ask, why Winter -> Summer -> Spring
- it's what the client wants! :)
A "simple" CASE should perform better since the expression is only evaluated once.
And right(issue, -5)
is equivalent to substring(issue, 6, 100)
, but a bit faster:
SELECT npid, title, url, issue
FROM tbl
ORDER BY left(issue, 4) DESC
,CASE right(issue, -5)
WHEN 'Winter' THEN 1
WHEN 'First_Quarter' THEN 1
WHEN 'Summer' THEN 2
WHEN 'Second_Quarter' THEN 2
WHEN 'Spring' THEN 3
WHEN 'Third_Quarter' THEN 3
WHEN 'Fall' THEN 4
WHEN 'Fourth Quarter' THEN 4
ELSE 5
END;
left() and right() have been added with PostgreSQL 9.1. The trick with right()
is to use a negative number to trim a constant number of characters from the left.
These are equivalent (for strings of <= 100 characters):
SELECT substring(issue from 6 for 100) AS substring1
,substring(issue, 6, 100) AS substring2
,substring(issue, 6) AS substring3
,substr(issue, 6, 100) AS substr1
,substr(issue, 6) AS substr2
,right(issue, -5) AS right0
FROM tbl
-> sqlfiddle