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 verschachtelten CASE Ausdrücke, die mindestens O(n^2) wenn n ist die Anzahl der Parameter für GREATEST
War es hilfreich?

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>

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top