Frage

Gibt es eine Möglichkeit, eine Transact SQL-Anweisung neu zu schreiben, die eine CASE verwendet, wenn Struktur das gleiche zu tun, ohne den Fall zu verwenden, wenn?

Ich bin mit einem Produkt, das einen integrierten Abfrage-Designer und seinen eigenen Pseudo-SQL hat. Es hat seine Grenzen auf, was ich mit SQL Server und Oracle verwenden kann. Also habe ich diese Spalte, die, wenn die zugrunde liegende Datenbank Oracle, verwendet DECODE (das unterstützt wird). Allerdings muss ich es mit SQL Server und CASE funktioniert, wenn sie nicht unterstützt wird.

Die Aussage, die ich bin versucht zu konvertieren so etwas wie

Decode (StatusColumn,  'Value 1',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 2',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 3',
Decode(Sign(Now()-TargetDateColumn)),1,'Past
Due', 'Outstanding'),  'Value 4')

Ich habe eine begrenzte Anzahl an T-SQL-Optionen und CASE zu verwenden, wenn keine Option ist. Ich habe IsNull und Coalesce, aber ich bin nicht sicher, ob sie mich mit diesem helfen.

Sie nicht mit den Datumsberechnungen Mühe, jene gelöst werden.

Ich suchte den Fall, dass Fragen hier, ohne Erfolg.

Danke!

Update:

Ich weiß, dass ich für die Beschränkungen mehr Details über den Grund gegeben haben sollte, da dies eine Ressource Entwickler ist, und es wäre davon ausgegangen wird, dass dies ein Entwicklungsprodukt ist. Es ist nicht.

Ich verwende ein Enterprise-Software-Produkt, das einen integrierten Abfrage-Designer und seinen eigenen Pseudo-SQL hat. Es hat seine Grenzen auf, was ich mit SQL Server und Oracle verwenden kann. Im Grunde alles, was nicht das Parsen der integrierten Abfrage-Engine nicht brechen Spiel. Das bedeutet, dass alle sanktionierten Funktionen und Ausdrücke, sowie all Datenabstraktionen (interne Objekte, die in einer Datenbank zu einer physischen Tabelle entsprechen und andere mit dem Produkt erstellt Abfragen), plus alles, was von Oracle SQL oder Transact SQL, die nicht explizit das Parsen nicht brechen .

Der Grund, warum CASE WHEN nicht für mich funktioniert ist, dass es das Parsen des pseudo-SQL von der Abfrage-Engine bricht.

Schließlich möchte ich versuchen:

  1. Verwenden Sie nur die Abfrage des Produkts Designer die SQL, die die Pässe Parsen ODER
  2. Verwenden Sie ein paar zusätzliche Ressourcen aus die SQL Server-Datenbank und die Abfrage-Designer, um es getan.

Auf der Grundlage der mehr guten Antworten, die ich habe, hier ist der Ansatz, der für mich gearbeitet, so weit.

Jason DeFontes schlug vor, dass ich eine Datenbank-View verwenden, könnte der Fall, wenn Regeln und fällt in # 2 oben auszuführen. Es funktioniert für mich, weil eine Ansicht ist dynamisch genug, dass ich es nicht tun Wartung auf (im Gegensatz zu richartallent Wahrheit Tabellen Ansatz gegenüber, die ich zu Jason Ansatz sind in der Nähe glauben). Pascal Vorschlag von einer Funktion zu schaffen auf der gleichen Linie gehen würde, aber wahrscheinlich den Parsing brechen.

Also habe ich eine Datenbank Ansicht, die die Transformation alle mit CASE tut, wenn ich es zu meiner Abfrage SQL, trat er mit dem vorhandenen SQL und es funktionierte gut. Ich weiß, dass ich wahrscheinlich einen Overhead auf den Datenbank-Engine hinzugefügt, da sie die gleichen Daten zweimal auf abrufen müssen (eine für die Ansicht und einen für die Abfrage), aber es ist einer jener Fälle, in denen es kaum ein Problem.

Da diese „eine Ansicht verwenden, um zu verschleiern es“ Design funktioniert für mich, ich frage mich, was der effizienteren Ansatz wäre:

  • Mit einer Auswahl mit CASE WHEN;
  • Verwenden von CTE (wieder richardtallent);
  • Verwenden von Union All (HLGEM);
  • Verwenden von Unterabfragen (MisterZimbu);

Ich werde noch Aramis wyler Vorschlag prüfen, wie es wohl in # 1 oben fallen könnte.

Für den Moment war Jasons Antwort akzeptiert. Bedenkt man, dass ich CASE verwendet, wenn in der Ansicht, vielleicht der Titel für das Wesen endete Frage ist schlecht gewählt. Ich upped jeden, der etwas vorgeschlagen, dass in dem Prozess geholfen. Ich weiß nicht, ob das einen Unterschied in Ihrem Ruf macht oder nicht, aber ich dachte, es war die nette Sache zu tun.

Auch hier möchte ich Ihnen allen für Ihre Hilfe danken und bitten Sie, alles auf die Frage zu bearbeiten, die Sie nicht angemessen gefallen ist (es ist meine erste Frage und Englisch ist meine zweite Sprache).

War es hilfreich?

Lösung

Können Sie die CASE / Wenn die Logik in eine Ansicht verschieben, dann das Werkzeug Abfrage die Ansicht haben?

Andere Tipps

Haben Sie Vereinigung alle zur Verfügung? Vielleicht könnte man sich zusammen, um eine Abfrage für jede der Bedingungen mit dem Zustand des Falles inder where-Klausel und Vereinigung schreiben.

Kann schreiben Sie benutzerdefinierte Unterabfragen? Wahrscheinlich nicht, wenn Sie haben nicht einmal Zugang zu CASE WHEN, aber dies würde auch wahrscheinlich funktionieren:

select
    ...,
    coalesce(c1.value, c2.value, c3.value, ..., <default value>)
from MyTable
left join (select <result 1> as value) c1 on <first condition>
left join (select <result 2> as value) c2 on <second condition>
left join (select <result 3> as value) c3 on <third condition>

Schreiben Sie eine Funktion, die die Berechnung mit CASE durchführt, wenn.

Es ist hässlich und in Abhängigkeit von der Anzahl der Werte haben Sie es nicht lebensfähig sein kann. Aber streng genommen, ich glaube, so etwas wie dies als Übersetzung aus dem obigen Abfrage Segment funktionieren würde:

wählen Sie 'PastDue' aus dem Tabellenname Now ()> TargetDateColumn und (StatusColumn = 'Wert 1' oder StatusColumn = 'Value 2' oder StatusColumn = 'Wert 3')   union select 'Outstanding' where Now ()

Ich bin mir nicht ganz sicher, ob ich den Code zu verstehen, aber das sollte man einen anderen Ansatz eine Idee geben.

Erstellen Sie zunächst eine Tabelle:

CREATE TABLE StatusLookup(
   value nvarchar(255),
   datesign shortint,
   result varchar(255));

Nun, füllen Sie es mit einer Wahrheitstabelle (viele wiederholten Logik hier offenbar, vielleicht diese zwei Wahrheitstabellen mit CROSS JOIN zwischen ihnen sein sollen):

INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 1', 1, 'Past Due')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 2', 1, 'Past Due')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', -1, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', 0, 'Outstanding')
INSERT INTO StatusLookup(value, datesign, result) VALUES ('Value 3', 1, 'Past Due')

Schließlich verbinden und eine Standard-Antwort geben:

SELECT mytable.*, COALESCE(statuslookup.result, 'Value 4')
FROM
    mytable LEFT JOIN statuslookup ON
        statuslookup.value = StatusColumn
        AND statuslookup.datesign = Sign(Now()-TargetDateColumn)

Ein wesentlicher Vorteil dieses Ansatzes ist es setzt die Business-Logik in Datentabellen, nicht-Code, die oft mehr wartbar und erweiterbar.

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