CASE ORDER BY con più colonne, e le diverse opzioni di ordinamento
-
16-10-2019 - |
Domanda
Sto tentando di usare un CASE ORDER BY
T-SQL in una stored procedure in cui sono passato parametro @OrderBy come TINYINT.
-
@Orderby = 1 Then Date column should be ASC
-
@Orderby = 2 Then Date column should be DESC
La mia domanda è: Come posso ottenere la colonna della data di sorta disc quando sono passato un 2 per quel parametro, e hanno l'asc una stringa colonna di ordinamento nello stesso ordine CASO PER istruzione
Questo è quello che ho adesso per la CASE ORDER BY
ORDER BY
CASE WHEN @OrderBy = 1 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) + tp.LastName + tp.FirstName END ,
CASE WHEN @OrderBy = 2 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) + tp.LastName + tp.FirstName END DESC
Questa Codici analizza e restituisce un set di risultati senza errori, ma il 2 ° CASO ORDER BY è tutto in ordinamento DESC, quando io preferirei avere ccd.CertEndDate DESC, tp.LastName ASC, ASC tp.FirstName
Grazie in anticipo.
Soluzione
Interruzione fuori un po 'di più:
ORDER BY CASE WHEN @orderby = 1 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) END ASC,
CASE WHEN @orderby = 2 THEN CONVERT(NVARCHAR(30) , ccd.CertEndDate) END DESC,
tp.lastname ASC,
tp.firstname ASC
Hai solo bisogno l'ordinamento ai cambiamenti sul primo campo, in modo da non racchiudere gli altri nella CASE
.
Si deve notare che non includiamo un ELSE
per ogni CASE
, il che significa che qualsiasi altro valore tornerà NULL
e essere scartato dal ORDER BY
.
Altri suggerimenti
Con la risposta di JNK, si potrebbe anche prendere in considerazione:
DECLARE @Example TABLE
(
first_name NVARCHAR(50) NOT NULL,
last_name NVARCHAR(50) NOT NULL,
cert_end_date DATE NOT NULL,
other_columns NCHAR(100) NOT NULL DEFAULT (N'')
UNIQUE (cert_end_date ASC, first_name, last_name),
UNIQUE (cert_end_date DESC, first_name, last_name)
)
INSERT @Example
(first_name, last_name, cert_end_date)
VALUES
('a', 'w', '2008-12-31'),
('b', 'x', '2009-12-31'),
('c', 'y', '2010-12-31'),
('d', 'z', '2011-12-31')
DECLARE
@order_date_ascending BIT = CONVERT(BIT, 'true')
-- 1. May require an explicit sort despite useful indexes
SELECT
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
ORDER BY
CASE WHEN @order_date_ascending = 1 THEN e.cert_end_date END ASC,
CASE WHEN @order_date_ascending = 0 THEN e.cert_end_date END DESC,
e.first_name ASC,
e.last_name ASC
-- 2. Conditional statements
IF @order_date_ascending = CONVERT(BIT, 'true')
BEGIN
SELECT
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
ORDER BY
e.cert_end_date ASC,
e.first_name ASC,
e.last_name ASC
END
ELSE IF @order_date_ascending = CONVERT(BIT, 'false')
BEGIN
SELECT
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
ORDER BY
e.cert_end_date DESC,
e.first_name ASC,
e.last_name ASC
END
-- 3. Union All & Start-up Filters
SELECT * FROM
(
SELECT TOP (9223372036854775807)
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
WHERE
@order_date_ascending = CONVERT(BIT, 'true')
ORDER BY
e.cert_end_date ASC,
e.first_name ASC,
e.last_name ASC
) AS sort_asc
UNION ALL
SELECT * FROM
(
SELECT TOP (9223372036854775807)
e.first_name,
e.last_name,
e.cert_end_date
FROM @Example AS e
WHERE
@order_date_ascending = CONVERT(BIT, 'false')
ORDER BY
e.cert_end_date DESC,
e.first_name ASC,
e.last_name ASC
) AS sort_desc
La prima e la terza metodi possono beneficiare del Parametro Embedding ottimizzazione disponibili su SQL Server 2008 SP1 CU5 se si verifica una compilation-livello di istruzione, o è costretto a verificarsi utilizzando l'hint di query OPTION (RECOMPILE)
. Vedere questo MSDN blog per i dettagli.
Il terzo metodo non richiede una raccolta di volta in volta, dal momento che gli operatori di filtro nel piano di avere un'espressione Start-Up. Sottoalbero piano sotto ogni filtro viene eseguito solo se la condizione restituisce true.