首页 > 解决方案 > 使用 Group By 时无法按名称排序

问题描述

我正在使用以下 SQL 查询将数据插入临时表

INSERT INTO @tmp_Notify 
    SELECT     'U' + CONVERT(varchar,UserId), CONVERT([varchar](50), [FirstName]) + ' ' + CONVERT([varchar](50), [LastName])
    FROM  [User] 
            INNER JOIN dbo.UserGroup ON UserId = FkUserId  
            INNER JOIN [Group] ON GroupId = FkGroupId 
    GROUP BY UserId, CONVERT([varchar](50), [FirstName]), CONVERT([varchar](50), [LastName])
    HAVING MIN(GroupLevel) >= @minGroup
    ORDER BY CONVERT([varchar](50), [FirstName]), CONVERT([varchar](50), [LastName])

我插入几个数据如下,

将组数据插入为

INSERT INTO @tmp_Notify 
    SELECT     'G' + CONVERT(varchar,GroupId), 'Group - ' + GroupName
    FROM  [Group] 
    WHERE GroupLevel >= @minGroup AND IsActive = 1
    ORDER BY GroupName

所以我需要先显示用户名列表,然后按 GroupName 顺序显示组名。

我的完整代码是

    --Users of the same group as currently logged in user and userÆs of higher groups
    INSERT INTO @tmp_Notify 
        SELECT     'U' + CONVERT(varchar,UserId), CONVERT([varchar](50), DECRYPTBYKEY([FirstName])) + ' ' + CONVERT([varchar](50), DECRYPTBYKEY([LastName]))
        FROM  [User] 
                INNER JOIN dbo.UserGroup ON UserId = FkUserId  
                INNER JOIN [Group] ON GroupId = FkGroupId 
        GROUP BY UserId, CONVERT([varchar](50), DECRYPTBYKEY([FirstName])), CONVERT([varchar](50), DECRYPTBYKEY([LastName]))
        HAVING MIN(GroupLevel) >= @minGroup
        ORDER BY CONVERT([varchar](50), DECRYPTBYKEY([FirstName])), CONVERT([varchar](50), DECRYPTBYKEY([LastName]))

    select * from @tmp_Notify

    --Currently logged in userÆs group and higher groups
    INSERT INTO @tmp_Notify 
        SELECT     'G' + CONVERT(varchar,GroupId), 'Group - ' + GroupName
        FROM  [Group] 
        WHERE GroupLevel >= @minGroup AND IsActive = 1
--      GROUP BY GroupId, GroupName
--      HAVING MIN(GroupLevel) >= @minGroup
        ORDER BY GroupName
END
ELSE
BEGIN
    INSERT INTO @tmp_Notify VALUES('Me','Me')

    IF((SELECT FkSupervisor FROM [User] WHERE UserId = @currentUser) IS NOT NULL)
    BEGIN
        INSERT INTO @tmp_Notify VALUES('Supervisor','Supervisor')
    END
END

    --List Option (to allow a list of email addresses)
    INSERT INTO @tmp_Notify VALUES('List','List')   

    --SELECT * FROM @tmp_Notify tn order by tn.NotifyName
    SELECT * FROM @tmp_Notify

但它不是正确的顺序,我需要按FirstNameand对数据进行排序LastName。我该怎么做

我的预期输出是

U10059  Emily Windrow
U10039  Esta Kulzer
U10030  Ileana Conklin
U10040  Kamala Millerbernd
U10007  Katherine Tayan
G110    Group - Managers
G112    Group - Membership Officers
G113    Group - Mortgage
G108    Group - Operations Administrator
G109    Group - PFS
List    List

标签: sqlsql-servergroup-bysql-order-by

解决方案


这是一个普遍的误解。

向插入语句添加顺序没有任何意义,因为原始数据表没有内在的保证顺序。在 SQL Server 中,无论数据进入的顺序如何,它都将存储在聚集索引中,因此按此排序。它也将被添加到表中可能再次不同的任何其他索引中。如果您根本没有索引并且您的表是一个堆,那么无论您做什么,订单都无法确定。

当您查询表时,没有默认保证的数据将按顺序返回,除非您使用 ORDER BY 指定它。如果没有这个,返回的数据理论上可以是任何顺序(SQL Server 将按照允许它在最快时间内完成查询的任何顺序输出)。

您将数据放入表中的顺序与您将其再次取出的顺序无关。


推荐阅读