SQL: ORDER BY using a substring within a specific column… possible?

前端 未结 7 749
清酒与你
清酒与你 2020-11-30 12:02

I have a database whose columns are npID, title, URL, and issue.

Here is an example of two years\' entries:

npID               title               UR         


        
7条回答
  •  温柔的废话
    2020-11-30 12:32

    Standard SQL

    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! :)

    Optimize performance

    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.

    Syntax variants

    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

提交回复
热议问题