SQL:ORDER BY使用特定列中的子字符串...可能吗?

Brd*_*rds 7 sql sorting substring

我有一个数据库,其列是npID,标题,URL和问题.

以下是两年条目的示例:

npID               title               URL               issue
88                 EMR Newsletter      a.com             2010 Third_Quarter
89                 EMR Newsletter      b.com             2010 Second_Quarter
43                 EMR Newsletter      c.com             2010 First_Quarter
47                 EMR Newsletter      d.com             2009 Winter
45                 EMR Newsletter      e.com             2009 Summer
46                 EMR Newsletter      f.com             2009 Spring
44                 EMR Newsletter      g.com             2009 Fall
Run Code Online (Sandbox Code Playgroud)

我想要做的是能够根据"问题"列中的子字符串对结果进行排序.然而,直到2010年,客户使用季节作为标题,并在2010年,他们开始使用季度.在"ORDER BY"中是否有一种方法我可以提供一个单词列表来排序是否/何时在"问题"值中找到它们?

我希望最终结果是这样的:

npID               title               URL               issue
43                 EMR Newsletter      c.com             2010 First_Quarter
89                 EMR Newsletter      b.com             2010 Second_Quarter
88                 EMR Newsletter      a.com             2010 Third_Quarter
47                 EMR Newsletter      d.com             2009 Winter
45                 EMR Newsletter      e.com             2009 Summer
46                 EMR Newsletter      f.com             2009 Spring
44                 EMR Newsletter      g.com             2009 Fall
Run Code Online (Sandbox Code Playgroud)

Tom*_*m H 11

您可以在其中添加一个CASE声明ORDER BY来完成此操作.更好的途径是更改应用程序和表,以便在您有开发时间时将这些相关数据实际存储在它所属的列中.

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
Run Code Online (Sandbox Code Playgroud)

订购您想要的季节.您也可以通过调整CASE语句以特定方式(Q1后跟Spring,然后是Q2等)对它们进行排序.


Erw*_*ter 8

标准SQL

尝试一下CASE声明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;
Run Code Online (Sandbox Code Playgroud)

不要问,为什么Winter -> Summer -> Spring- 这是客户想要的!:)

优化性能

"简单"CASE应该表现得更好,因为表达式只被评估一次.
right(issue, -5)就相当于substring(issue, 6, 100),但有点快:

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;
Run Code Online (Sandbox Code Playgroud)

left()right()已添加PostgreSQL 9.1.诀窍right()是使用负数来修剪左边的常数字符.

语法变体

这些是等效的(对于<= 100个字符的字符串):

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
Run Code Online (Sandbox Code Playgroud)

- > sqlfiddle