Fallbestellung durch mit mehreren Spalten und verschiedenen Sortieroptionen
-
16-10-2019 - |
Frage
Ich versuche, einen T-SQL zu verwenden CASE ORDER BY
In einem gespeicherten Verfahren, bei dem ich als Tinyint @Orderby -Parameter bestanden werde.
@Orderby = 1 Then Date column should be ASC
@Orderby = 2 Then Date column should be DESC
Meine Frage lautet: Wie kann ich die Datumsspalte zum Sortieren von Des sortieren, wenn ich für diesen Parameter eine 2 übergeben werde, und die A -Sortierung der A -Stringspalte in derselben Fallreihenfolge nach Anweisung zu haben?
Das habe ich jetzt für die 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
Dies codiert Parsen und gibt ein Ergebnis ohne Fehler zurück. Die 2. Fallordnung von ist alles in der Desc -Sortierreihenfolge, wenn ich lieber CCD.Certenddate Desc, tp.lastname ASC, tp.firstname ASC haben würde
Danke im Voraus.
Lösung
Brechen Sie es ein bisschen mehr aus:
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
Sie brauchen nur die Sortierreihenfolge, um im ersten Feld zu ändern. Schalten Sie die anderen nicht in die CASE
.
Es ist zu beachten, dass wir keine einbeziehen ELSE
für jeden CASE
, was bedeutet, dass jeder andere Wert zurücksetzt NULL
und von der verworfen werden ORDER BY
.
Andere Tipps
Zusammen mit JNKs Antwort können Sie auch in Betracht ziehen:
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
Die erste und dritte Methoden können von der Parameter-Einbettungsoptimierung profitieren, die auf SQL Server 2008 SP1 CU5 verfügbar ist, wenn eine Zusammenstellung auf Anweisungsebene auftritt oder mit dem erzwungen wird, mit dem auftreten zu können OPTION (RECOMPILE)
Abfrage Hinweis. Sieh dir das an MSDN Blog Eintrag für Details.
Die dritte Methode erfordert nicht jedes Mal eine Zusammenstellung, da die Filterbetreiber im Plan einen Start-up-Ausdruck haben. Der Plan-Unterbaum unter jedem Filter wird nur ausgeführt, wenn die Bedingung true bewertet wird.