Wie zu simulieren GREATEST() in Sybase ASE?
-
27-10-2019 - |
Frage
Die meisten Datenbanken haben so etwas wie eine GREATEST
Funktion, die nützlich sein können einige Male.Zumindest diese Datenbanken nicht über eine solche Funktion:
- Derby
- SQL Server
- Sybase ASE
- Sybase SQL Anywhere
Für SQL Server und Sybase SQL Anywhere, kann die Funktion simuliert werden mithilfe von Unterabfragen und UNION ALL
, wie gesehen werden kann, in diese Frage hier.Ein Beispiel:
-- SELECT GREATEST(field1, field2, field3) FROM my_table
SELECT (SELECT MAX(c) FROM
(SELECT my_table.field1 AS c UNION ALL
SELECT my_table.field2 UNION ALL
SELECT my_table.field3) T) AS greatest
FROM my_table
Aber das funktioniert nicht in Sybase ASE.Offenbar, die Unterabfragen nicht haben, den Zugang zu den äußeren Abfrage my_table
Referenz.Der Fehler, den ich bekomme, ist
Die Spalte Präfix 'my_table' nicht übereinstimmen mit einem Tabellennamen oder alias-name in der Abfrage verwendet wird.Entweder die Tabelle ist nicht in der FROM-Klausel oder hat es eine Korrelation Namen, die muss verwendet werden, statt
Hinweis: dieses problem scheint nicht mit Sybase SQL Anywhere.Irgendeine Idee was hier schief und wie könnte ich re-schreiben Sie die Anfrage?
Ich würde gerne vermeiden
- Gespeicherten Funktionen, so kann ich nicht die notwendigen Zuschüsse, um Sie zu erstellen
- Langen
CASE
Ausdrücke, die Ausdruck der Länge der Kombination permutation alle Vergleiche benötigt, mit verschachteltenCASE
Ausdrücke, die mindestensO(n^2)
wennn
ist die Anzahl der Parameter fürGREATEST
Lösung
Wie ich es verstehe, sind die Logik (ignorieren null-Werte) ist
SELECT CASE
WHEN field1 >= field2
AND field1 >= field3
THEN field1
WHEN field2 >= field3
THEN field2
ELSE field3
END AS greatest
FROM my_table;
...sollte aber nur null zurückgeben, wenn alle Werte null sind.
Ich denke, das ist mehr wie ich möchte in der Lage sein, Dinge tun (obwohl, Sybase ASE nicht unterstützt common table expressions):
WITH my_table
AS
(
SELECT *
FROM (
VALUES ('A', 1, 2, 3),
('B', 2, 3, 1),
('C', 3, 1, 2),
('D', NULL, 2, 3),
('E', NULL, NULL, 3),
('F', NULL, 3, NULL),
('G', 1, NULL, 3),
('H', 1, 3, NULL),
('X', NULL, NULL, NULL)
) AS T (ID, field1, field2, field3)
),
T1
AS
(
SELECT ID, field1 AS field_n
FROM my_table
UNION
SELECT ID, field2 AS field_n
FROM my_table
UNION
SELECT ID, field3 AS field_n
FROM my_table
)
SELECT ID, MAX(field_n) AS greatest
FROM T1
GROUP
BY ID;
Andere Tipps
In diesem Fall werde ich hinzufügen extra CASE
.
SELECT
CASE WHEN field1 IS NOT NULL
AND field2 IS NOT NULL
AND field3 IS NOT NULL THEN
CASE WHEN field1 >= field2
AND field1 >= field3
THEN field1
WHEN field2 >= field3
THEN field2
ELSE field3
END
ELSE
NULL
END AS greatest
FROM my_table
Die folgenden SQL-Klausel ist noch präziser als onedaywhen Antwort, obwohl Sie sind semantisch äquivalent:
SELECT CASE WHEN field1 >= ALL(field2, field3, field4) THEN field1
WHEN field2 >= ALL( field3, field4) THEN field2
WHEN field3 >= ALL( field4) THEN field3
ELSE field4
END AS greatest
FROM my_table;
Dies ist schließlich eine seltene und noch schöner Anwendungsfall für diejenigen, die Quantoren, die kaum jemand benutzt in SQL.Siehe auch diese Frage:
SQL JEGLICHE und EINIGE Schlüsselwörter, die Synonyme, die in alle SQL-Dialekte?
Leider ist diese syntax wird nicht unterstützt alle SQL-Dialekte, als die ALL
Quantifizierer ususally erwartet <table subquery>