Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie gehe ich mit einer Spalte mit unterschiedlichen Werten in derselben Zeile in SQL um?

Bezüglich der vorangegangenen Bemerkungen zum Tabellendesign gibt es in der Tat eine Redundanz in der Tabelle; Sie könnten den Empname in einer anderen Tabelle speichern, die Sie hier mit Ihrer Tabelle verbinden würden, um dies zu vermeiden. Jede Redundanz ist ein potenzieller Widerspruch. Wenn wir jedoch ein Tabellendesign haben, das für das Abfragen und Minimieren notwendiger Joins optimiert ist, könnte es in einem Batch-Job von woanders gefüllt werden, und dann wäre das Design angemessen.

Was Sie hier tun möchten, wird oft als "horizontales Schwenken" bezeichnet. Uns fehlen hier einige Informationen, daher gehe ich von einer maximalen Anzahl von Ausleihen von 2 aus. Wir brauchen einen Mechanismus, der es uns ermöglicht, Daten in Spalte 1 oder Spalte 2 abzulegen. je nachdem, ob es die erste oder zweite Reihe für das gleiche Empno ist. Deshalb generieren wir eine Sequenznummer. Schließlich verwenden wir einen SUM(CASE seq WHEN ...)-Ausdruck in Verbindung mit einem GROUP BY, um die Anzahl der Zeilen zu reduzieren und die Tabelle zu glätten.

Hier geht's:

-- first global table expression - the input table
-- The table could exist already, and then this would not be needed.
WITH foo(empno,empname,loanref,amount) AS (
          SELECT  1,'abc',123,100
UNION ALL SELECT  1,'abc',456,200
)
-- second global table expression - add sequence number
-- this needs to be in the query
,    foo_numbered AS (
SELECT
  -- need a number: 1 for the first, 2 for the second loan
  ROW_NUMBER() OVER(PARTITION BY empname ORDER BY loanref) AS seq
, *
FROM foo
)
SELECT
  empno
, empname
, MAX(CASE seq WHEN 1 THEN loanref END) AS loanref_1
, SUM(CASE seq WHEN 1 THEN amount END) AS amount_1
, MAX(CASE seq WHEN 2 THEN loanref END) AS loanref_2
, SUM(CASE seq WHEN 2 THEN amount END) AS amount_2
FROM foo_numbered
GROUP BY
  empno
, empname
;

Viel Spaß beim Spielen

Markus