2 Stimmen

TSQL: Select aus der Menge der Spalten mit dem niedrigsten positiven Wert

Beispiel Schema:

RowID    Quantity    ModifiedPrice    GroupPrice    CustomPrice    SalePrice
----------------------------------------------------------------------------
1        5           20.00            0             15.00          17.00
2        2           14.00            7.00          22.00          0
3        9           10.00            10.00         0              11.00

Ausgehend von dieser Beispieltabelle möchte ich in der Lage sein, den niedrigsten Wert, der nicht Null ist, zwischen den vier *Preis-Spalten auf möglichst effiziente/einfache Weise auszuwählen.

Beispiel Ausgabe:

RowID    Quantity    EndPrice
------------------------------
1        5           15.00
2        2           7.00
3        9           10.00

Für zusätzliche Informationen, die DB ist SQL Server 2005.

4voto

Quassnoi Punkte 396418
SELECT  RowId, Quantity,
        (
        SELECT  MIN(price)
        FROM    (
                SELECT  ModifiedPrice AS price
                UNION ALL
                SELECT  GroupPrice
                UNION ALL
                SELECT  CustomPrice
                UNION ALL
                SELECT  SalePrice
                ) qi
        WHERE   price > 0
        )
FROM    mytable

Dies ist besser lesbar als ein Haufen von CASE Erklärungen.

Beachten Sie jedoch, dass es hier um 4 mal so langsam wie CASE Erklärungen.

Hier ist das Testskript, das die Daten analysiert und korrekte Ergebnisse liefert:

CREATE TABLE #t_prices
        (
        RowID INT NOT NULL,
        Quantity INT NOT NULL,
        ModifiedPrice FLOAT NOT NULL,
        GroupPrice FLOAT NOT NULL,
        CustomPrice FLOAT NOT NULL,
        SalePrice FLOAT NOT NULL
        )

INSERT
INTO    #t_prices
VALUES  (1, 5, 20.00, 0, 15.00, 17.00)
INSERT
INTO    #t_prices
VALUES  (2, 2, 14.00, 7.00, 22.00, 0)
INSERT
INTO    #t_prices
VALUES  (3, 9, 10.00, 10.00, 0, 11.000)

SELECT  RowId, Quantity,
        (
        SELECT  MIN(price)
        FROM    (
                SELECT  ModifiedPrice AS price
                UNION ALL
                SELECT  GroupPrice
                UNION ALL
                SELECT  CustomPrice
                UNION ALL
                SELECT  SalePrice
                ) qi
        WHERE   price > 0
        )
FROM    #t_prices

3voto

Paul Chernoch Punkte 4865

Ich würde eine Fallanweisung verwenden:

CASE
  WHEN condition THEN trueresult
  [...n]
[ELSE elseresult]
END

Beginnen Sie mit einer übersichtlichen Antwort und nehmen Sie an, dass keiner der Werte NULL ist:

CASE 
  WHEN ModifiedPrice > GroupPrice AND ModifiedPrice > CustomPrice AND ModifiedPrice > SalePrice THEN ModifiedPrice
  WHEN GroupPrice > CustomPrice AND GroupPrice > SalePrice THEN GroupPrice
  WHEN CustomPrice > SalePrice THEN CustomPrice
  ELSE SalePrice
END

Wenn irgendwelche Werte NULL sind, dann geben diese Klauseln false zurück, also müssen wir ISNULL verwenden, um die Dinge in Ordnung zu bringen und NULLS durch eine große negative Zahl oder Null ersetzen, wenn Sie keine negativen Preise erwarten. In der Annahme, dass es keine negativen Preise gibt, werde ich Null verwenden.

CASE 
  WHEN ModifiedPrice > ISNULL(GroupPrice, 0) AND ModifiedPrice > ISNULL(CustomPrice, 0) AND ModifiedPrice > ISNULL(SalePrice,0) THEN ModifiedPrice
  WHEN GroupPrice > ISNULL(CustomPrice, 0) AND GroupPrice > ISNULL(SalePrice, 0) THEN GroupPrice
  WHEN CustomPrice > ISNULL(SalePrice, 0) THEN CustomPrice
  ELSE ISNULL(SalePrice, 0)
END

Nicht schön, aber es wird funktionieren. Wenn Sie eine Statistik erstellen, um festzustellen, welche Spalte normalerweise den größten Wert aufweist, können Sie die Abfrage so ändern, dass diese Spalte zuerst getestet wird. (Sie können meine WHEN-Klauseln nicht einfach umstellen, da sie jeweils davon ausgehen, dass der vorherige Preis bereits abgelehnt wurde. Wenn CustomPrice normalerweise der größte Wert wäre, würde ich ModifiedPrice und CustomPrice im obigen Code vertauschen).

0voto

Dan F Punkte 11764

Ich bin ein bisschen spät dran mit dieser speziellen Frage, aber UNPIVOT hätte auch hier nützlich sein können. 4 Spalten ist wahrscheinlich nicht so schlimm, aber wenn Sie 30 Spalten betrachten, die Sie aufheben möchten, ist UNPIVOT ein Geschenk des Himmels :-)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X