Case When mit Window Function

Mr. Robot

Fleissiger Benutzer
Beiträge
88
Hallo zusammen,

ich bin gerade wieder etwas aus der Übung...

Ich habe eine Spalte folgender Form:

WERT / NAME
1 A
1 A
1 A
1 BC
1 BC
1 BC
2 A
2 A
2 A
2 CD
2 CD
2 CD

und möchte eine dritte Spalte wie folgt

WERT / NAME / NEUESPALTE
1 A BC
1 A BC
1 A BC
1 BC BC
1 BC BC
1 BC BC
2 A CD
2 A CD
2 A CD
2 CD CD
2 CD CD
2 CD CD

Also eine Kombination aus Window Function und CASE WHEN... sowas wie
CASE WHEN [NAME] = 'BC' THEN
'BC' OVER (PARTITION BY [WERT]) AS NEUESPALTE

CASE WHEN [NAME] = 'CD' THEN
'CD' OVER (PARTITION BY [WERT]) AS NEUESPALTE

Insbesondere würde es mich interessieren ob man nach einer Partition einfach einen namen statt Aggregation vergeben kann.
 
Zuletzt bearbeitet:
Werbung:
Für mich sieht es grad so aus, als ob es eine direkte Abhängigkeit zwischen Spalte Wert und Spalte Neuespalte gibt.
1 = BC
2 = CD

Vielleicht habe ich es falsch verstanden, so oder so könntest Du Deine Frage etwas präzisieren.
Und was auch manchmal cool ist: Welchen Nutzen soll das haben?

Es wird zwar in Foren gern verlangt, kompakte und abstrahierte Beispiele zu nehmen, um ein Problem zu schildern. Aber ohne den Anwendungsfall oder ein kompatibles Szenario kann die Abstraktion nach hinten los gehen, also die Lösung am Problem vorbei.
 
Nein keine Beziehung und es werden später mehrere Kategorien geben. BC sind sowas wie Werte für ein Quartal. Die BC Werte für das andere Quartal sollen die gleichen sein wie A. Ich möchte somit eine Filter Möglichkeit schaffen, so dass ich BC Werte für das ganze Jahr filtern kann. Kann leider in der Datenlieferung nicht gesteuert werden.
 
Werbung:
Hallo Datenbank-Neuling.

wenn ich deine Beschreibung richtig verstanden habe, benötigst du eigentlich nur in einer weiteren Spalte abhängig vom Feld "Wert" einen korrigierte Bezeichnung zu Spalte "Name".
In dem Falle ist die Verwendung einer Window-Funktion nicht notwendig. Mir sind spontan vier verschiedene Lösungswege eingefallen:

  1. Verwendung der Funktion CHOOSE() (hier dazu mehr: CHOOSE (Transact-SQL) - SQL Server )
  2. verwenden einer Referenz-Tabelle
  3. CASE... WHEN ... THEN
  4. mit einer CTE im Abfrage-Kontext

ich habe hier mal einen kleinen Code geschrieben, der die 4 Ideen auffasst. Alle Abfragen ergeben das gleiche Ergebnis:

Code:
-- Tabelle mit den zu verarbeitenden Werten
DECLARE  @TA TABLE
(
    Wert int,
    [Name] varchar(255)
)

INSERT INTO @TA (Wert, [Name])
VALUES
(1,'A'),
(1,'A'),
(1, 'A'),
(1, 'BC'),
(1, 'BC'),
(1, 'BC'),
(2, 'A'),
(2, 'A'),
(2, 'A'),
(2, 'CD'),
(2, 'CD'),
(2, 'CD'),
(3, 'A'),
(3, 'A'),
(3, 'BC'),
(3, 'BC'),
(3, 'CD'),
(3, 'CD'),
(4, 'AB')


-- Lösung 1 mit CHOOSE (ab SQL Server 2012)
-- Gut bei wenigen, aufeinanderfolgenden Werten ind er Spalte [Wert]
SELECT
Wert,
Name,
CHOOSE(Wert, 'AB', 'BC', 'CD') as NeueSpalte
FROM @TA


-- Lösung 2 mit CASE...WHEN...
-- besser, wenn die Werte isn Spalte [Wert] Sprünge aufweisen
SELECT
Wert,
Name,
(CASE    WHEN Wert = 1 THEN 'AB'
        WHEN Wert = 2 THEN 'BC'
        WHEN Wert = 3 THEN 'CD'
ELSE '' END) as NeueSpalte
FROM @TA


--Lösung 3 mit Referenz-Tabelle - Geht immer, kann man innerhalb einer Abfrage aufbauen oder fest implementieren
-- Hier erst einmal mit Ansatz einer fest implementierten Tabelle - die deklarierte Tabelle kann man auch ale temporäre Tabelle
-- oder eben als Tabelle in der Datenbank implenemtieren
DECLARE @Werte TABLE
(
    Wert int PRIMARY KEY,
    NeueSpalte varchar(25)
)

INSERT INTO @Werte (Wert, NeueSpalte)
VALUES
(1, 'AB'),
(2, 'BC'),
(3, 'CD')

SELECT
a.Wert,
a.Name,
w.NeueSpalte
FROM @TA a

LEFT OUTER JOIN @Werte w
    ON w.Wert = a.Wert

-- Und dann die Lösung mir einer im Abfrage-Kontext generierten Tabelle (CTE)
;WITH cte_Werte
AS
(
    SELECT 1 as Wert, 'AB' as NeueSpalte
    UNION SELECT 2 as Wert, 'BC' as NeueSpalte
    UNION SELECT 3 as Wert, 'CD' as NeueSpalte
)

SELECT
a.Wert,
a.Name,
w.NeueSpalte
FROM @TA a

LEFT OUTER JOIN cte_Werte w
    ON w.Wert = a.Wert

Ich bin mir zwar nicht absolut sicher, ob ich deine Anforderung wirklich korrekt verstanden habe, aber nach dem, was ich deuten konnte, kommt das dem zumindest nahe.
Ich habe die Zuordnung der Übersetzung jetzt auf die Spalte [Wert] bezogen, das kann man aber natürlich auf jede beliebige Spalte anpassen (außer Funktion CHOOSE() - die macht nur Sinn bei Integer-Werten mit aufsteigender Reihenfolge ohne Sprünge in den zahlen).

Viele Grüße,
Tommi
 
Zuletzt bearbeitet:
Zurück
Oben