Как поместить предложение ORDER BY в SQL между UNIONS - PullRequest
5 голосов
/ 16 июня 2011

Я хочу реализовать простой запрос SQL, который будет возвращать отсортированный список. Проблема в том, что я получаю синтаксические ошибки для размещения предложения ORDER BY в любом месте, где я его поместил.

SELECT 
    fr.FunctionRoleID, fr.FunctionRoleInternalName
FROM 
    users u 
JOIN 
    UserRoles ur ON ur.UserID = u.UserID
JOIN 
    Roles_FunctionRoles rfr ON rfr.RoleID = ur.RoleID
JOIN 
    FunctionRoles fr ON fr.FunctionRoleID = rfr.FunctionRoleID 
WHERE 
    u.UserName = @UserName
    AND u.Active = 1

UNION 

SELECT 
    fr.FunctionRoleID, fr.FunctionRoleInternalName
FROM 
    Roles r
JOIN 
    Roles_FunctionRoles rfr ON rfr.RoleID = r.RoleID
JOIN 
    FunctionRoles fr ON fr.FunctionRoleID = rfr.FunctionRoleID
WHERE 
    r.RoleName = 'Authenticated Users'
    AND @UserName IS NOT NULL
    AND LEN(@UserName) > 0

Что я хочу вставить:

ORDER BY fr.DisplayName ASC

EDIT

Если я создаю подзапрос, используя

SELECT * 
FROM 
     (
     [my initial query]
     )
ORDER BY 
    [COLUMN NAME] ASC

Я получаю следующее сообщение об ошибке:

Неверный синтаксис рядом с 'ЗАКАЗАТЬ'. Ожидаемый 'AS', 'ID' или 'QUOTED_id'

Ответы [ 6 ]

2 голосов
/ 16 июня 2011

Вы не выбрали DisplayName, поэтому вы не можете использовать его для ORDER BY набора, полученного из UNION.Если вы хотите заказать по нему и опустить его в результатах;

;WITH T (FunctionRoleID, FunctionRoleInternalName, DisplayName) AS (
    SELECT 
        fr.FunctionRoleID, fr.FunctionRoleInternalName, fr.DisplayName
    FROM users u
        JOIN UserRoles ur ON ur.UserID = u.UserID
        JOIN Roles_FunctionRoles rfr ON rfr.RoleID = ur.RoleID
        JOIN FunctionRoles fr ON fr.FunctionRoleID = rfr.FunctionRoleID 
    WHERE 
        u.UserName = @UserName
    AND 
        u.Active = 1

    UNION

    SELECT 
        fr.FunctionRoleID, fr.FunctionRoleInternalName, fr.DisplayName
    FROM 
        Roles r
        JOIN Roles_FunctionRoles rfr ON rfr.RoleID = r.RoleID
        JOIN FunctionRoles fr ON fr.FunctionRoleID = rfr.FunctionRoleID
    WHERE 
        r.RoleName = 'Authenticated Users'
        and @UserName is not null and LEN(@UserName) > 0
)
SELECT 
    FunctionRoleID, FunctionRoleInternalName
FROM T
    ORDER BY DisplayName
2 голосов
/ 16 июня 2011

Предложение ORDER BY необходимо поместить после последнего оператора SELECT для Union.

2 голосов
/ 16 июня 2011

В большинстве баз данных вы можете поместить order by только в конце объединения.

Поскольку объединение абстрагирует псевдонимы отдельных таблиц, вам нужно только указать имя столбца.Так что пропустите fr.:

ORDER BY DisplayName
2 голосов
/ 16 июня 2011
select * from(
*what you have there*
) as foo
order by DisplayName ASC

Я не нахожусь перед IDE, поэтому синтаксис может быть немного отключен, но это идея.

e: да, подумал, что я расшифрую синтаксис ... добавлен псевдоним:)

1 голос
/ 16 июня 2011

Попробуйте

SELECT * FROM (

SELECT  
    fr.FunctionRoleID, fr.FunctionRoleInternalName 



FROM  
    users u  
    JOIN UserRoles ur ON ur.UserID = u.UserID 
    JOIN Roles_FunctionRoles rfr ON rfr.RoleID = ur.RoleID 
    JOIN FunctionRoles fr ON fr.FunctionRoleID = rfr.FunctionRoleID  


WHERE  
    u.UserName = @UserName 
AND  
    u.Active = 1 


UNION  

    SELECT  
        fr.FunctionRoleID, fr.FunctionRoleInternalName 
    FROM  
        Roles r 
        JOIN Roles_FunctionRoles rfr ON rfr.RoleID = r.RoleID 
        JOIN FunctionRoles fr ON fr.FunctionRoleID = rfr.FunctionRoleID 
    WHERE  
        r.RoleName = 'Authenticated Users' 
        and @UserName is not null and LEN(@UserName) > 0 ) a

ORDER BY a.FunctionRoleInternalName ASC

По сути, вы выбираете результат UNION, а затем выполняете ORDER BY ... обратите внимание, что я использую "FunctionRoleInternalName" ... вы можете изменить это значение на "DiaplayName", только если вы используете его в качестве столбца ALIAS в запросах UNION ... например "FunctionRoleInternalName AS DisplayName"

0 голосов
/ 16 июня 2011

Для UNION, ORDER BY идет в конце и применяется к объединенному результату обоих запросов; вы не можете упорядочить по столбцу, который не выбран обоими запросами в объединении.

вам нужно выбрать fr.DisplayName в обоих запросах; тогда вы можете заказать по нему.

Если вы не хотите, чтобы отображаемое имя было одним из выходных столбцов, вложите все это во внешний запрос, который извлекает только нужные столбцы.

...