Tabel saya didefinisikan sebagai: (ini adalah pelacakan konfigurasi metrik sederhana)

        CREATE TABLE IF NOT EXISTS strategy_registry (
        name            VARCHAR     NOT NULL,
        symbol          VARCHAR     NOT NULL,
        predictor_id    VARCHAR     NOT NULL,
        params          jsonb       NOT NULL,
        metric          FLOAT       NOT NULL,
        PRIMARY KEY(name, symbol, predictor_id)
        );

Dan pada konflik penyisipan, saya ingin mempertahankan metrik maksimum dan kolom params, dari versi yang mendapatkan nilai metrik maksimum. Saya menggunakan TimescaleDB (postgres 12)

    INSERT INTO strategy_registry (name, symbol, predictor_id, params, metric)
    VALUES ({{ name }}, {{ symbol }}, {{ predictor_id }}, {{ params }}, {{ metric }})
    ON CONFLICT (name, symbol, predictor_id) 
    DO UPDATE SET 
    (metric, params) = max(existing, excluded), params of greatest `metric` column value;
2
ntakouris 7 Januari 2021, 23:28

2 jawaban

Jawaban Terbaik

Saya tidak berpikir Anda dapat menangani kedua kolom secara bersamaan. Sesuatu seperti ini seharusnya berfungsi:

INSERT INTO strategy_registry (name, symbol, predictor_id, params, metric)
VALUES ({{ name }}, {{ symbol }}, {{ predictor_id }}, {{ params }}, {{ metric }})
  ON CONFLICT (name, symbol, predictor_id) 
    DO UPDATE 
      SET params = CASE 
                     WHEN metric < EXCLUDED.metric THEN EXCLUDED.params
                     ELSE params
                   END,
          metric = GREATEST(metric, EXCLUDED.metric);
0
Mike Organek 7 Januari 2021, 22:16

Fungsi yang Anda cari adalah terbesar(...) bukan maks. Max adalah fungsi kolom yang bekerja pada seluruh himpunan baris, dalam hal ini dalam tabel. Greatest memilih nilai 'maksimum' dari daftar nilai (atau variabel). Contoh:

select greatest(1,4,3,5,7,0)

Mengembalikan 7. Ini juga dapat digunakan dalam tugas sebagai

something = greatest(...);
4
Belayer 7 Januari 2021, 21:08