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

Oracle ke PostgreSQL:sintaks gabungan luar ANSI di PostgreSQL

Kami menemukan diri kami di artikel ketiga dalam seri migrasi Oracle. Kali ini, kita melihat operator aneh yang memodifikasi kriteria klausa WHERE di Oracle (+). Seperti yang lainnya, PostgreSQL memiliki solusi untuk itu.

GABUNG KANAN

Oracle mendukung, dan banyak pengembang menggunakan, sintaks ANSI outer JOIN menggunakan operator ke klausa kualifikasi.

Biasanya, itu terlihat seperti ini:

SELECT *
FROM person, places
WHERE person.id = places.person_id(+)

Tujuan dari sintaks ini adalah gabungan luar kanan. Dalam istilah teori himpunan, ini adalah himpunan bagian yang mencakup semua tempat, terlepas dari orangnya.

Hasil dari sampel kecil akan terlihat seperti ini:

id nama_belakang nama_depan id lokasi person_id
1 (NULL) (NULL) 1 Dallas (NULL)
2 Roybal Kirk 2 London 2
3 Riggs Simon 3 Paris 3

Sintaks ini tidak didukung di PostgreSQL.

Untuk mencapai hasil yang sama, Anda akan menggunakan sintaks SQL standar untuk gabungan luar.

SELECT *
FROM persons
RIGHT JOIN places
ON persons.id = places.person_id;

SQL juga menyediakan keterangan klarifikasi OUTER . Clarifier ini sepenuhnya opsional, karena setiap RIGHT JOIN menurut definisi adalah OUTER bergabung.

GABUNG LENGKAP

Demikian pula, menggunakan sintaks Oracle untuk bergabung penuh tidak berfungsi di PostgreSQL.

SELECT *
FROM persons, places
WHERE persons.id(+) = places(+);

Tujuan dari sintaks ini adalah daftar lengkap orang dan tempat apakah seseorang diasosiasikan dengan suatu tempat atau tidak.

Hasilnya akan seperti ini:

id nama_belakang nama_pertama** id lokasi person_id
1 (NULL) (NULL) 1 Dallas (NULL)
2 Roybal Kirk 2 London 2
3 Riggs Simon 3 Paris 3
4 Andrew Ganteng (NULL) (NULL) (NULL)

Menggunakan sintaks PostgreSQL, kueri akan ditulis sebagai berikut:

SELECT *
FROM persons
FULL JOIN places
ON persons.id = places.person_id;

Sekali lagi, OUTER kata kunci sepenuhnya opsional.

GABUNG LINTAS

Salah satu keuntungan berbeda dari pendekatan menggunakan kata kunci daripada hubungan implisit adalah Anda tidak dapat membuat produk silang secara tidak sengaja.

Sintaksnya:

SELECT *
FROM persons
LEFT JOIN places;

Akan menghasilkan kesalahan:

ERROR:  syntax error at or near ";"

Menunjukkan bahwa pernyataan tidak lengkap pada penanda akhir baris “;”.

PostgreSQL akan membuat produk gabungan silang menggunakan sintaks ANSI.

SELECT *
FROM persons, places;
id nama_belakang nama_depan id lokasi person_id
1 Sialan Andrew 1 Dallas (null)
1 Sialan Andrew 2 London 2
1 Sialan Andrew 3 Paris 3
1 Sialan Andrew 4 Madrid (null)
2 Kerajaan Kirk 1 Dallas (null)
2 Kerajaan Kirk 2 London 2
2 Kerajaan Kirk 3 Paris 3
2 Kerajaan Kirk 4 Madrid (null)
3 Riggs Simon 1 Dallas (null)
3 Riggs Simon 2 London 2
3 Riggs Simon 3 Paris 3
3 Riggs Simon 4 Madrid (null)
6 Wong Tandai 1 Dallas (null)
6 Wong Tandai 2 London 2
6 Wong Tandai 3 Paris 3
6 Wong Tandai 4 Madrid (null)

Yang lebih mungkin merupakan kesalahan pengkodean daripada hasil yang disengaja.

Untuk mendapatkan fungsi ini dengan sengaja, disarankan untuk menggunakan CROSS JOIN pernyataan.

SELECT *
FROM persons
CROSS JOIN places;

Dengan demikian memperjelas apa yang dimaksud dalam pernyataan tersebut.

GABUNG ALAMI

PostgreSQL mendukung NATURAL JOIN sintaks, tetapi sedikit diprotes.

SELECT *
FROM persons
NATURAL JOIN places;

Ini menghasilkan hasil berikut.

id nama_belakang nama_depan induk_id lokasi person_id
1 Sialan Andrew (null) Dallas (null)
2 Kerajaan Kirk 1 London 2
3 Riggs Simon 1 Paris 3

Namun, sintaks ini adalah masalah. Untuk contoh kita, kolom “id” di kedua tabel tidak ada hubungannya satu sama lain . Penggabungan ini telah membuahkan hasil, tetapi hasil dengan konten yang sama sekali tidak relevan.

Selain itu, Anda mungkin memiliki kueri yang awalnya menyajikan hasil yang benar, tetapi pernyataan DDL berikutnya diam-diam memengaruhi.

Pertimbangkan:

ALTER TABLE person ADD COLUMN places_id bigint;
ALTER TABLE places ADD COLUMN places_id bigint;
ALTER TABLE person ADD COLUMN person_id bigint;

Sekarang kolom apa NATURAL JOIN menggunakan? Pilihannya adalah id, place_id, person_id, dan semuanya di atas. Saya akan menyerahkan jawabannya sebagai latihan kepada pembaca.

Sintaks ini adalah bom waktu untuk kode Anda. Jangan menggunakannya.

Oke, jadi Anda tidak yakin. Nah, maka setidaknya memiliki beberapa konvensi pengkodean yang waras. Untuk tabel induk, beri nama kolom identitas “myparenttable_id”. Saat mereferensikannya dari relasi anak, gunakan nama yang sama, “myparenttable_id”. Jangan pernah menamai apapun dengan “id”, dan jangan pernah membuat referensi ke kolom dengan nama yang berbeda. Ah, lupakan saja. Jangan lakukan ini.

Anda mungkin tergoda untuk mengaburkan teka-teki sebelumnya dengan menggunakan USING kata kunci. Itu akan terlihat seperti ini:

SELECT *
FROM persons
JOIN places
USING (id);

Tapi USING kata kunci hanya dapat memanfaatkan kecocokan nama yang tepat di seluruh tabel. Yang sekali lagi, dalam contoh kita benar-benar salah.

Pilihan praktik terbaik untuk PostgreSQL adalah menghindari mendesain tabel dengan mengkodekan standar konvensi.

Ringkasan

Teknik kata kunci ini (vs. operator) juga tersedia di Oracle. Mereka lebih lintas platform, dan kurang ambigu. Itu saja akan membuat mereka menjadi praktik terbaik.

Selain itu, mereka mengekspos kesalahan logis ketika digunakan secara tidak benar. Untuk pengembangan apa pun di PostgreSQL, kami merekomendasikan penggunaan kata kunci eksplisit secara sepihak.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menerapkan Pengaturan Multi-Pusat Data untuk PostgreSQL - Bagian Satu

  2. Gabungkan satu kolom dalam kueri dengan banyak kolom

  3. ClassNotFoundException dengan PostgreSQL dan JDBC

  4. PostgreSQL array_agg order

  5. Kembali ke readline versi 6.x di Homebrew untuk memperbaiki Postgresql?