SQL: ORDER BY с использованием подстроки в определенном столбце ... возможно? - PullRequest
5 голосов
/ 18 ноября 2011

У меня есть база данных, столбцами которой являются 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

Что я хотел бы сделать, так это уметь сортировать результаты на основе подстрок в столбце «Проблема». Однако до 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

Ответы [ 7 ]

10 голосов
/ 18 ноября 2011

Вы можете поместить оператор 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

Порядок сезонов, как вы хотите.Вы также можете заказать их особым образом (Q1, затем Spring, Q2 и т. Д.), Настроив оператор CASE.

7 голосов
/ 18 ноября 2011

Стандартный 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;

Не спрашивайте, почему 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;

left() и right() были добавлены в PostgreSQL 9.1.Хитрость с right() состоит в том, чтобы использовать отрицательное число для обрезки постоянного числа символов слева.

Варианты синтаксиса

Они эквивалентны (для строк<= 100 символов): </p>

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

1 голос
/ 18 ноября 2011

Вот вариант той же темы

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
0 голосов
/ 03 октября 2016
SELECT Column1, row_number() over(order by substring(column2,280,9)) 
FROM YourTable 

Это даст order by столбца подстроки 2.

0 голосов
/ 18 ноября 2011

Попробуйте этот подход (это в 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
0 голосов
/ 18 ноября 2011

Да, вы можете использовать конструкции if / then в любом месте команды sql.

У вас уже есть шаблон подстроки, который вам подходит?если это так, вы можете использовать что-то вроде:

ORDER BY (IF (SUBSTRING(first_match_of_issue) IS NOT NULL) THEN first_match_of_issue ELSE second_match_of_issue))

Однако - если вы уже знаете, какими они будут, то утверждения CASE, упомянутые в других ответах, вероятно, будут проще.

0 голосов
/ 18 ноября 2011

Вы можете сделать часть подстроки выбранных данных

SELECT npId, title, URL, issue, SUBSTRING(issue, 4) AS strsort FROM tbl ORDER BY strsort, issue
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...