PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL:assegna un valore a ciascuna riga in base a criteri

Note:

  1. Se la tua formula funziona effettivamente in Excel, hai memorizzato le date nelle celle, non l'ora.
  2. Per D, E , non capisco come questo dovrebbe restituire "sì" quando la riga precedente non ha la stessa etichetta
  3. Devi aggiungere alcune colonne con ID alla tua tabella (!). Mentre Excel mantiene lo stesso ordine delle righe nel foglio (a meno che non lo modifichi esplicitamente), PostgreSQL no. Pertanto, se hai davvero solo tempo nel tempo delle colonne, non è possibile ottenere lo stesso ordine di righe che hai nella tabella, portando a risultati completamente errati.
  4. Se stai usando la versione 8.4, il tuo link è corretto, tuttavia sarebbe meglio se utilizzi l'attuale documentazione

Dati:

drop table if exists tmp.test;

create table tmp.test (id int, ddate date, label varchar, ttime time);

insert into tmp.test values

(1, '2014/6/4','A','12:05:56'),
(2, '2014/6/4','A','23:02:32'),
(3, '2014/6/4','B','8:39:25'),
(4, '2014/6/4','B','12:36:37'),
(5, '2014/6/4','C','12:20:43'),
(6, '2014/6/4','C','12:56:44'),
(7, '2014/6/4','D','20:52:22'),
(8, '2014/6/4','E','22:25:30'),
(9, '2014/6/4','F','12:16:15'),
(10, '2014/6/4','F','12:31:09'),
(11, '2014/6/4','F','7:12:06'),
(12, '2014/6/4','G','7:48:32'),
(13, '2014/6/4','H','17:58:11');

Domanda:

select
  id, 
  ddate,
  label,
  ttime,
  case when (lag(ttime) over(partition by label order by id))::interval
        + ttime::interval > interval '24 hours' then 'yes' else 'no' end
  -- ,(lag(ttime) over(partition by label order by ttime))::interval + ttime::interval
from
  tmp.test

Spiegazione:

  1. lag la funzione otterrà il valore nella riga precedente per una determinata partizione. Nel nostro caso, la partizione è definita da label.
  2. operatore di trasmissione :: cambierà time digita in interval , così possiamo aggiungere tempo e ottenere più di 24 ore.
  3. Confrontiamo il totale con l'intervallo di 24 ore e mostriamo una bella etichetta yes o no .

Aggiornamento:

select
  id, 
  ddate,
  label,
  ttime,
  case when lead(label) over(partition by label order by id) is null then 'no' else 'yes' end
from
  tmp.test