如何在全名列上按姓氏排序?

时间:2010-06-16 13:21:09

标签: sql-server

我有一个名为FullName的SQL表,其中包含“John Smith”。

如何按FullName列中显示的姓氏订购数据?

对于像Laurence John Fishburne这样的长名字,我想用“Fishburne”这个词来订购数据。

因此,名称按顺序存储

  • 名字
  • 中间名
  • 姓氏

我使用的是Microsoft SQL Server 2005。

8 个答案:

答案 0 :(得分:7)

我会做类似的事情:

SELECT FullName
FROM TABLE
ORDER BY REVERSE(SUBSTRING(REVERSE(FullName), 0, CHARINDEX(' ', REVERSE(FullName)))) 

答案 1 :(得分:5)

您可以使用计算列将实际值保存到可以像使用任何其他列一样使用的列中,而不是计算每次运行查询时的姓氏。

ALTER TABLE Customer
    ADD LastName AS 
        RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1) PERSISTED

这将LastName列添加到Customer表中,使用指定的函数计算姓氏的值,并将其存储到物理表中。最后需要关键字PERSISTED才能将值保存到磁盘,否则每次运行查询时都会计算它。

编辑: 处理没有空格的值:

ALTER TABLE Customer
    ADD LastName AS 
    case when CHARINDEX(' ', REVERSE(FullName)) > 0
    then RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1) 
    else
    FullName
    end
    PERSISTED

虽然您可以使用此功能,但您将确定在这种情况下会发生什么。我的观点是表明可以使用案例陈述。您可能还希望将所有输​​出路径转换为相同类型以避免类型不匹配。

答案 2 :(得分:2)

试试这个,它使用最少数量的函数来查找FullName字符串中的最后一个空格,这应该有助于提高性能:

DECLARE @YourTable table (FullNamevarchar(30))

INSERT @YourTable VALUES ('Harry Smith');
INSERT @YourTable VALUES ('John Davis');
INSERT @YourTable VALUES ('Allision Thomas Williams');

SELECT
    FullName
        ,RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1) AS SortBy
    FROM @YourTable
    ORDER BY RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1)

输出:

FullName                       SortBy
------------------------------ ------------------------------
John Davis                     Davis
Harry Smith                    Smith
Allision Thomas Williams       Williams

(3 row(s) affected)

为了获得最佳性能和最准确的排序,您需要将名称拆分为Firstname,MiddleName和LastName字段。只有输入数据的用户才能真正理解FullName的哪个部分是姓氏。

答案 3 :(得分:2)

<强>查询

SELECT stringrowname FROM tablename 
ORDER BY SUBSTRING_INDEX((stringrowname)," ",-1);

它将按最后一个字返回字符串顺序。

答案 4 :(得分:1)

create table foo(fullname varchar(100))
go

insert into foo values ('Harry Smith');
insert into foo values ('John Davis');
insert into foo values ('Allision Thomas Williams');

SELECT fullname
     , REVERSE(left(REVERSE(fullname), charindex(' ',REVERSE(fullname))-1))
  FROM foo
ORDER BY REVERSE(left(REVERSE(fullname), charindex(' ',REVERSE(fullname))-1))

输出:

fullname                   (No column name)
John Davis                  Davis
Harry Smith                 Smith
Allision Thomas Williams    Williams

答案 5 :(得分:1)

如有疑问,请自己动手:

Select
*
From
Users
Order By
LTrim(Reverse(Left(Reverse(FullName), CharIndex(' ', Reverse(FullName))))) Asc,
FullName Asc -- Fall-over for when there isn't a last name

答案 6 :(得分:1)

这样可以解决问题:

create table #tmpTable
(
    ID int identity(1,1) primary key,
    FullName varchar(100) not null
);

insert into #tmpTable(FullName) values('Big John Sansom');
insert into #tmpTable(FullName) values('Mike Douglas Reid');
insert into #tmpTable(FullName) values('First Second Last');
insert into #tmpTable(FullName) values('JustOneTokenForName');

select 
    FullName,
    LastName = case 
        when CHARINDEX(FullName,' ') = 0 THEN FullName
        else RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1)
    end
from #tmpTable
order by LastName

drop table #tmpTable

答案 7 :(得分:0)

这实际上取决于名称的存储方式。假设“Last,First Middle”你可以做类似

的事情
order by substring(0, charindex(',', FullName))

你可能需要稍微调整一下,但我相信这应该有用。