PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Masukkan data dan atur kunci asing dengan Postgres

Tabel users harus memiliki beberapa kunci utama yang tidak Anda ungkapkan. Untuk tujuan jawaban ini saya akan menamakannya users_id .

Anda dapat menyelesaikan ini dengan agak elegan dengan CTE pengubah data diperkenalkan dengan PostgreSQL 9.1 :

country unik

Seluruh operasi agak sepele dalam hal ini:

WITH i AS (
    INSERT INTO addresses (country) 
    SELECT country
    FROM   users
    WHERE  address_id IS NULL 
    RETURNING id, country
    )
UPDATE users u
SET    address_id = i.id
FROM   i
WHERE  i.country = u.country;

Anda menyebutkan versi 8.3 dalam pertanyaan Anda. Meningkatkan! Postgres 8.3 telah mencapai akhir masa pakainya.

Bagaimanapun, ini cukup sederhana dengan versi 8.3. Anda hanya perlu dua pernyataan:

INSERT INTO addresses (country) 
SELECT country
FROM   users
WHERE  address_id IS NULL;

UPDATE users u
SET    address_id = a.id
FROM   addresses a
WHERE  address_id IS NULL 
AND    a.country = u.country;

country tidak unik

Itu lebih menantang. Anda bisa cukup buat satu alamat dan tautkan beberapa kali. Tapi Anda memang menyebutkan hubungan 1:1 yang mengesampingkan solusi yang begitu mudah.

WITH s AS (
    SELECT users_id, country
         , row_number() OVER (PARTITION BY country) AS rn
    FROM   users
    WHERE  address_id IS NULL 
    )
    , i AS (
    INSERT INTO addresses (country) 
    SELECT country
    FROM   s
    RETURNING id, country
    )
    , r AS (
    SELECT *
         , row_number() OVER (PARTITION BY country) AS rn
    FROM   i
    )
UPDATE users u
SET    address_id = r.id
FROM   r
JOIN   s USING (country, rn)    -- select exactly one id for every user
WHERE  u.users_id = s.users_id
AND    u.address_id IS NULL;

Karena tidak ada cara untuk secara jelas menetapkan satu id dikembalikan dari INSERT untuk setiap pengguna dalam satu set dengan country yang identik , saya menggunakan fungsi jendela row_number() untuk membuatnya unik.

Tidak langsung dengan Postgres 8.3 . Salah satu cara yang mungkin:

INSERT INTO addresses (country) 
SELECT DISTINCT country -- pick just one per set of dupes
FROM   users
WHERE  address_id IS NULL;

UPDATE users u
SET    address_id = a.id
FROM   addresses a
WHERE  a.country = u.country
AND    u.address_id IS NULL
AND NOT EXISTS (
    SELECT * FROM addresses b
    WHERE  b.country = a.country
    AND    b.users_id < a.users_id
    ); -- effectively picking the smallest users_id per set of dupes

Ulangi ini sampai NULL terakhir nilai hilang dari users.address_id .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana Anda membuat string acak yang cocok untuk ID sesi di PostgreSQL?

  2. Cara memeriksa status server PostgreSQL Mac OS X

  3. Skrip shell untuk menjalankan perintah pgsql dalam file

  4. Bagaimana cara menyalin dari file CSV ke tabel PostgreSQL dengan header dalam file CSV?

  5. Bagaimana Atan() Bekerja di PostgreSQL