如何在 UNION 之间的 SQL 中放置 ORDER BY 子句

Posted

技术标签:

【中文标题】如何在 UNION 之间的 SQL 中放置 ORDER BY 子句【英文标题】:How to place an ORDER BY clause in SQL between UNIONS 【发布时间】:2011-09-16 11:40:31 【问题描述】:

我想实现将返回排序列表的简单 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

编辑

如果我使用

创建子查询
SELECT * 
FROM 
     (
     [my initial query]
     )
ORDER BY 
    [COLUMN NAME] ASC

我收到以下错误消息:

“ORDER”附近的语法不正确。应为“AS”、“ID”或“QUOTED_id”

【问题讨论】:

它缺少派生表的别名。 【参考方案1】:

在大多数数据库中,您只能在联合末尾放置 order by

因为联合会抽象出单个表别名,所以您只需列出列名。所以省略fr.

ORDER BY DisplayName

【讨论】:

【参考方案2】:

ORDER BY 子句需要放在 Union 的最后一条 SELECT 语句之后。

【讨论】:

【参考方案3】:
select * from(
*what you have there*
) as foo
order by DisplayName ASC

我不在 IDE 前面,所以语法可能有点不对,但就是这样。

e:是的,我想我会提高语法...添加了别名:)

【讨论】:

不需要子查询,虽然也没有什么坏处 好的,我刚刚尝试了这种方法,我收到另一个错误消息:'ORDER' 附近的语法不正确。应为“AS”、“ID”或“QUOTED_ID” 只记得给你的派生表添加一个别名。大多数 RDBMS 都需要它【参考方案4】:

您没有选择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

【讨论】:

这很好,只有一件事,您必须从最后一个 SELECT 中删除表别名 .fr,只需使用列名 FunctionRoleID 就可以完美地工作! +1 用于发现 DisplayName 不在选择列表中:)【参考方案5】:

试试

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"

【讨论】:

【参考方案6】:

对于UNIONORDER BY 放在最后并应用于两个查询的组合结果;您不能按未由联合中的两个查询选择的列进行排序。

您需要做的是在两个查询中选择 fr.DisplayName;那么你可以通过它订购。

如果您不希望显示名称成为输出列之一,请将整个内容嵌套在仅检索您想要的列的外部查询中。

【讨论】:

以上是关于如何在 UNION 之间的 SQL 中放置 ORDER BY 子句的主要内容,如果未能解决你的问题,请参考以下文章

如何在中间的android中放置带有文本的元素之间的分隔线?

如何在 tkinter ~ python 中放置在网格中的两个小部件之间添加空间?

如何使用 MakeCode 在 Minecraft 中放置半块板

SQL - 在日期桶中放置值

如何在 html 中放置 if 以使 'object.star' 的值同时等于 1 和 2

如果另一列中的值是唯一的,那么如何在SQL中放置一个显示1的列,如果它是重复的则为0?