Oracle
 sql >> Database >  >> RDS >> Oracle

Come fare su una colonna con valori diversi in una stessa riga in sql?

Per quanto riguarda i commenti precedenti sul design della tabella - c'è, infatti, una ridondanza nella tabella; potresti memorizzare l'empname in un'altra tabella, a cui uniresti la tua tabella qui per evitarlo; ogni ridondanza è una potenziale contraddizione. Tuttavia, se abbiamo un design di tabella ottimizzato per eseguire query e ridurre al minimo i join necessari, potrebbe essere popolato in un processo batch da qualche altra parte e quindi il design sarebbe appropriato.

Quello che vuoi fare qui viene spesso definito "perno orizzontale". Ci mancano alcune informazioni qui, quindi presumo un numero massimo di prestiti di 2. Abbiamo bisogno di un meccanismo che ci permetta di inserire i dati in col1 o col2, a seconda che sia la prima o la seconda riga per lo stesso empno. Ecco perché generiamo un numero di sequenza. Infine, utilizziamo un'espressione SUM(CASE seq WHEN ...) insieme a GROUP BY per ridurre il numero di righe e appiattire la tabella.

Ecco:

-- 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
;

Buon gioco

Marco