У меня есть Таблица SQL со столбцом под названием FullName, который содержит, например, "John Smith".
Как может заказать данные фамилией, которая появляется в столбце FullName?
Для длинного имени как "Laurence John Fishburne" я хотел бы заказать данные словом "Fishburne".
Таким образом имена хранятся в порядке
Я использую Microsoft SQL Server 2005.
Когда сомневаетесь, сделайте это сами:
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
попробуйте это, он использует минимальное количество функций для поиска последнего пробела в строке 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 является фамилией.
Я бы сделал что-то вроде:
SELECT FullName
FROM TABLE
ORDER BY REVERSE(SUBSTRING(REVERSE(FullName), 0, CHARINDEX(' ', REVERSE(FullName))))
Вместо того, чтобы вычислять фамилию каждый раз, когда вы хотите выполнить запрос, вы можете иметь вычисляемый столбец, который сохраняет фактическое значение в столбец, который можно использовать так же, как и любой другой столбец.
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
Хотя вы можете возиться с этой функцией как угодно, чтобы определить, что произойдет в этом случае. Я хочу показать, что операторы case можно использовать. Возможно, вы также захотите привести все пути вывода к одному типу, чтобы избежать несоответствия типов.
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
Это поможет:
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
Это действительно зависит от того, как хранятся имена. Предполагая, что «Last, First Middle» вы могли бы сделать что-то вроде
order by substring(0, charindex(',', FullName))
. Возможно, вам придется немного повозиться с этим, но я считаю, что это должно сработать.