Это просто больно.Один метод, который хорошо обобщает, использует агрегацию.Производительность не такая хорошая, как при использовании CASE
, и предполагается, что строки имеют уникальный идентификатор:
SELECT DISTINCT id, MIN(ts) OVER (PARTITION BY id) as min_ts,
FIRST_VALUE(which) OVER (PARTITION BY id ORDER BY ts)
FROM ((SELECT id, 'timestamp_1' as which, timestamp_1 as ts
FROM time
) UNION ALL
(SELECT id, 'timestamp_2' as which, timestamp_2 as ts
FROM time
) UNION ALL
(SELECT id, 'timestamp_3' as which, timestamp_3 as ts
FROM time
) UNION ALL
(SELECT id, 'timestamp_4' as which, timestamp_4 as ts
FROM time
)
) t;
Я не фанат select distinct
, но Redshift не поддерживает first_value()
, так какфункция агрегирования.
Альтернативой является использование некоторого будущего значения, чтобы избежать NULL
:
select nullif(least(timestamp_1, timestamp_2, timestamp_3, timestamp_4), '9999-01-01') as least_ts,
(case when timestamp_1 = least(timestamp_1, timestamp_2, timestamp_3, timestamp_4) then 'timestamp_1'
when timestamp_2 = least(timestamp_1, timestamp_2, timestamp_3, timestamp_4) then 'timestamp_2'
when timestamp_3 = least(timestamp_1, timestamp_2, timestamp_3, timestamp_4) then 'timestamp_3'
else 'timestamp_4'
end) as which
from (select coalesce(timestamp_1, '9999-01-01') as timestamp_1,
coalesce(timestamp_2, '9999-01-01') as timestamp_2,
coalesce(timestamp_3, '9999-01-01') as timestamp_3,
coalesce(timestamp_4, '9999-01-01') as timestamp_4
from time
) t;
Примечание. Я предполагаю, что вы используете Redshift.У Postgres есть более простые способы сделать это.