Может быть более эффективный способ сделать это, но я думаю, что он даст вам то, о чем вы просите:
WITH x AS (
SELECT *
FROM (VALUES
('xys','txq','2020-03-01'::DATE,1),
('xys','txs','2020-03-08'::DATE,0),
('xys','txt','2020-03-12'::DATE,0),
('xyb','txl','2020-03-13'::DATE,0),
('xyb','txp','2020-03-14'::DATE,1)) as y (card_id, txn_id, date_, legit)
)
SELECT card_id,
CASE WHEN legit = 0 THEN txn_id
WHEN DATEDIFF('d',date_next,date_) <= 10 THEN txn_id_next
ELSE txn_id END as txn_id,
CASE WHEN legit = 0 THEN date_
WHEN DATEDIFF('d',date_next,date_) <= 10 THEN date_next
ELSE date_ END as date_,
CASE WHEN legit = 0 THEN legit
WHEN DATEDIFF('d',date_next,date_) <= 10 THEN legit_next
ELSE legit END as legit
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY card_id ORDER BY date_) as row_num,
LEAD(txn_id) OVER (PARTITION BY card_id ORDER BY date_) as txn_id_next,
LEAD(date_) OVER (PARTITION BY card_id ORDER BY date_) as date_next,
LEAD(legit) OVER (PARTITION BY card_id ORDER BY date_) as legit_next
FROM x
QUALIFY row_num = 1
);
Это сначала получает первую запись и «следующую запись» и перемещает их в одну строку, а затем операторы CASE
определяют, следует ли использовать первую запись или «следующую» запись на основе правил, которые, я думаю, вы указали.