select Staff_ID, First_Name, Last_Name
from YourTable
order by cast(Staff_ID as varchar(10))+First_Name+Last_Name,
Staff_ID
NULL wartości zostaną uporządkowane jako pierwsze.
Podczas łączenia wartości z NULL wynik to NULL więc First_Name+Last_Name będzie NULL jeśli którykolwiek jest NULL .
cast(Staff_ID as varchar(10))+... czy istnieje gwarancja żądanej kolejności w przypadku, gdy First_Name+Last_Name? jest nie NULL (Zakładam Staff_ID to int ).
I dodatkowe zamówienie według kolumny Staff_ID jest po to, aby zagwarantować żądaną kolejność dla wszystkich wierszy, w których First_Name+Last_Name jest NULL
Aktualizacja
Kwerendę można zbudować dynamicznie, korzystając z informacji_SCHEMA.KOLUMN. To może zrobić, co chcesz. Uwaga, nie jest to testowane dla wszystkich rodzajów danych.
declare @TableName sysname = 'YourTable'
declare @Sql nvarchar(max) = 'select * from '+quotename(@TableName)+ ' order by '
select @Sql = @Sql+'+cast('+COLUMN_NAME+' as varchar(max))'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @TableName
exec (@Sql)
Aktualizacja 2
Wersja niedynamiczna używająca zamiast tego XML.
;with C as
(
select *,
row_number() over(order by (select 1)) as rn
from YourTable
)
select C1.*
from C as C1
cross apply (select *
from C as C2
where C1.rn = C2.rn
for xml path('x'), type) as T(N)
order by T.N.value('count(/x/*)', 'int')
Aktualizacja 3
Jeśli znasz klucz podstawowy swojej tabeli i nie masz nic przeciwko wpisaniu klauzuli where, możesz użyć tego zamiast row_number() .
select Y1.*
from YourTable as Y1
order by (select *
from YourTable as Y2
where Y1.Staff_ID = Y2.Staff_ID
for xml path('x'), type).value('count(/x/*)', 'int')