Чем функция MS SQL Server похожа на функцию MySQL FIELD ()? - PullRequest
14 голосов
/ 08 октября 2010

MySQL предоставляет строковую функцию с именем FIELD () , которая принимает переменное число аргументов. Возвращаемое значение - это местоположение первого аргумента в списке остальных. Другими словами:

FIELD('d', 'a', 'b', 'c', 'd', 'e', 'f')

вернет 4, так как 'd' является четвертым аргументом после первого.

Эта функция позволяет сортировать результаты запроса на основе очень специфического порядка. Для моего текущего заявления у менеджера есть четыре статуса: активный, одобренный, отклоненный и отправленный. Однако, если я просто упорядочиваю по столбцу состояния, я чувствую, что удобство использования результирующего списка уменьшается, поскольку отклоненные и активные элементы состояния важнее отправленных и утвержденных.

В MySQL я мог бы сделать это:

SELECT <stuff> FROM <table> WHERE <conditions> ORDER BY FIELD(status, 'rejected', 'active','submitted', 'approved')

и результаты будут упорядочены таким образом, чтобы сначала брались отклоненные элементы, затем - активные и т. Д. Таким образом, результаты были упорядочены по убыванию уровня важности для посетителя.

Я мог бы создать отдельную таблицу, которая перечисляет этот уровень важности для статусов, а затем упорядочить запрос по нему в порядке убывания, но это возникало у меня несколько раз с момента перехода на MS SQL Server, поэтому я подумал, что узнать, могу ли я избежать дополнительной таблицы и несколько более сложных запросов, используя встроенную функцию, аналогичную функции MySQL FIELD ().

Спасибо,
Дэвид Кис

Ответы [ 3 ]

22 голосов
/ 08 октября 2010

Использовать выражение CASE (SQL Server 2005 +):

ORDER BY CASE status
           WHEN 'active' THEN 1
           WHEN 'approved' THEN 2
           WHEN 'rejected' THEN 3
           WHEN 'submitted' THEN 4
           ELSE 5
         END

Вы можете использовать этот синтаксис для более сложной оценки (включая комбинации или, если вам нужно использовать LIKE)

ORDER BY CASE 
           WHEN status LIKE 'active' THEN 1
           WHEN status LIKE 'approved' THEN 2
           WHEN status LIKE 'rejected' THEN 3
           WHEN status LIKE 'submitted' THEN 4
           ELSE 5
         END
0 голосов
/ 08 ноября 2018

Для вашего конкретного примера вы могли бы:

ORDER BY CHARINDEX(
    ',' + status + ',',
    ',rejected,active,submitted,approved,'
)

Обратите внимание, что FIELD должен был возвращать 0, 1, 2, 3, 4, где, как указано выше, будут возвращаться 0, 1, 10, 17 и 27, поэтому этот трюк полезен только в предложении order by.

0 голосов
/ 22 августа 2013

Я рекомендую CTE (SQL Server 2005+).Не нужно повторять коды состояния или создавать отдельную таблицу.

WITH cte(status, RN) AS (  -- CTE to create ordered list and define where clause
      SELECT 'active', 1
UNION SELECT 'approved', 2
UNION SELECT 'rejected', 3
UNION SELECT 'submitted', 4
)
SELECT <field1>, <field2>
FROM <table> tbl
INNER JOIN cte ON cte.status = tbl.status  -- do the join
ORDER BY cte.RN  -- use the ordering defined in the cte

Удачи,

Джейсон

...