Mengapa SQL ANTARA bersifat inklusif dan bukannya setengah terbuka?


45

Interval semi-terbuka (atau Setengah Terbuka, Setengah Tertutup , Setengah Berbatas ) ( [a,b), yang xtermasuk dalam interval iff a <= x < b) cukup umum pada pemrograman, karena mereka memiliki banyak properti yang mudah digunakan.

Adakah yang bisa menawarkan alasan yang menjelaskan mengapa SQL BETWEENmenggunakan interval tertutup ( [a,b])? Ini adalah esp. tidak nyaman untuk kencan. Mengapa Anda harus BETWEENbersikap seperti ini?


Saya ingin tahu, properti nyaman apa yang mereka miliki?
phant0m

2
jika tidak termasuk, bagaimana Anda dapat dengan mudah menanyakan semua nama belakang dalam rentang A ke D? atau nama W ke Z? Untuk angka antara 1 dan 10 Anda dapat mencari 0 <n <11, tetapi untuk karakter Anda harus menggunakan angka ASCII? atau nomor unicode? Plus, indeks dapat dengan mudah membawa Anda ke awal data Anda.
jqa

2
Saya memahami rasa frustrasi Anda, (StartDate> = '2010-01-01' dan StartDate <'2011-01-01'), berfungsi dengan baik, untuk menggunakan Antara yang setara akan menjadi (StartDate antara '2010-01-01' dan ' 2010-12-31 23:59:59 '), baik yang besar maupun yang perlu diketahui berapa hari di bulan Desember
Todd

1
@ phant0m [a, b) U [c, d) == [a, d). [a: int, b: int) persis mengandung elemen ba. Komentar Todd menunjukkan bagaimana mereka bekerja dengan sangat baik untuk kencan (yang paling saya rindukan) Pada dasarnya, ketika coding, interval semiopen cenderung lebih sederhana, lebih mudah digunakan dan kuat.
alex

Jawaban terbaik seharusnya merujuk dokumentasi keputusan obyektif dari orang-orang yang pertama kali menentukan ANTARA untuk SQL, dengan demikian menjawab Mengapa, daripada jawaban subjektif yang dipilih.
Todd

Jawaban:


48

Saya pikir inklusif BETWEENlebih intuitif (dan tampaknya, begitu pula para desainer SQL) daripada interval semi-terbuka. Misalnya, jika saya mengatakan "Pilih angka antara 1 dan 10", kebanyakan orang akan memasukkan angka 1 dan 10. Interval terbuka sebenarnya sangat membingungkan bagi non-pengembang karena asimetris. SQL kadang-kadang digunakan oleh non-programmer untuk membuat pertanyaan sederhana, dan semantik semi-terbuka akan jauh lebih membingungkan bagi mereka.


9
Contoh Anda berfokus pada bilangan bulat, untuk angka desimal dan jumlah terbatas lainnya (seperti tanggal), istilah di antara keduanya ambigu. Jika saya katakan sudahkah Anda melakukan X antara 2012 dan 2013, saya tidak termasuk 2013 (atau khususnya hari 2013-01-01)
Todd

4
@Todd Setiap penggunaan istilah ini bersifat mendua. Itulah sebabnya ahli matematika, ilmuwan, dan pemrogram yang cerdas mendokumentasikan niat mereka sebagai "setengah terbuka" atau semacamnya. Saya pikir inti dari jawaban Oleski adalah bahwa SQL pada awalnya ditujukan untuk pengguna akhir daripada programmer (sungguh!). Rupanya para desainer SQL mengambil definisi yang mereka pikir terbaik untuk audiens itu. Tetapi seperti yang disarankan oleh penulis Pertanyaan, setengah terbuka hampir selalu lebih baik untuk bekerja dengan rentang seperti rentang waktu.
Basil Bourque

"Saya pikir inklusif ANTARA lebih intuitif" bersifat subyektif. "SQL kadang-kadang digunakan oleh non-programmer untuk membuat pertanyaan sederhana" - Non-programmer sama-sama perlu memeriksa spesifikasi.
Todd


Pertanyaannya juga sering ditanyakan "Pilih nomor dari 1 hingga 10" (hanya untuk menghindari ambiguitas yang jelas). Sebagai catatan. Anda mengatakan "pilih angka antara 1 dan 10"; kebanyakan orang mungkin tidak akan memilih 1 atau 10. Memang itu lebih merupakan masalah psikologi. :) Orang masih akan menerima 1 dan 10 sebagai pilihan yang valid (meskipun secara semantik salah); tapi itu hasil interpretasi kontekstual dengan asumsi 1 dan 10 valid. Jika Anda mengatakan: "antara 13 dan 24" dan Anda lebih mungkin ditanya apakah 13 dan 24 disertakan.
Kecewa

26

PERTANYAAN: Mengapa SQL ANTARA inklusif?

JAWABAN: Karena desainer bahasa SQL membuat keputusan desain yang buruk, karena mereka gagal memberikan sintaksis yang akan memungkinkan pengembang untuk menentukan mana dari 4 varian BETWEEN (tertutup, semi-terbuka-kiri, semi-terbuka-kanan, atau terbuka). ) mereka lebih suka.

REKOMENDASI: Kecuali / sampai standar SQL diubah, jangan gunakan ANTARA tanggal / waktu. Alih-alih terbiasa dengan pengkodean perbandingan rentang DATE sebagai kondisi independen pada batas awal dan akhir dari ANTARA rentang Anda. Ini agak bertele-tele, tetapi akan membuat Anda menulis kondisi yang intuitif (sehingga kurang cenderung buggy) dan jelas untuk pengoptimal database, memungkinkan rencana eksekusi yang optimal untuk ditentukan dan indeks yang akan digunakan.

Misalnya, jika kueri Anda menerima spesifikasi hari input dan harus mengembalikan semua catatan yang jatuh pada tanggal tersebut, Anda akan mengkodekan sebagai:

  • WHERE DATE_FIELD >= :dt AND DATE_FIELD < :dt+1

Mencoba untuk menulis logika menggunakan ANTARA risiko kinerja dan / atau kode kereta. Tiga kesalahan langkah umum:

1) WHERE DATE_FIELD BETWEEN :dt AND :dt+1

Ini hampir pasti merupakan bug - pengguna mengharapkan untuk melihat hanya catatan untuk tanggal tertentu, namun suatu hari akan berakhir dengan laporan yang berisi catatan dari pukul 12:00 pagi hari berikutnya.

2) WHERE TRUNC(DATE_FIELD) = :dt

Memberikan jawaban yang benar, tetapi menerapkan fungsi ke DATE_FIELD akan membuat sebagian besar pengindeksan / statistik tidak berguna (meskipun kadang-kadang DBA akan mencoba membantu dengan menambahkan indeks berbasis fungsi ke bidang tanggal - masih membakar jam kerja dan ruang disk dan menambahkan overhead ke IUD operasi di atas meja)

3) WHERE EVENT_DATE BETWEEN :dt AND :dt + 1-1/24/60/60

Tom Kyte, guru Oracle yang luar biasa, merekomendasikan solusi IMO yang kurang elegan ini. Bekerja sangat baik sampai Anda menghabiskan sepanjang hari untuk menemukan bahwa "1-1 / 24/06/60" dalam kueri yang memberikan hasil tidak lengkap ... atau sampai Anda menggunakannya secara tidak sengaja di bidang TIMESTAMP. Plus, ini agak eksklusif; kompatibel dengan tipe data DATE Oracle (yang melacak ke yang kedua), tetapi perlu disesuaikan dengan ketepatan DATE / TIME dari berbagai produk database.

SOLUSI: Petisi komite SQL ANSI untuk meningkatkan spesifikasi bahasa SQL dengan memodifikasi sintaks ANTARA untuk mendukung spesifikasi alternatif ke standar TUTUP / INKLUSIF. Sesuatu seperti ini akan membantu:

expr1 ANTARA expr2 [ INCL [USIVE] | EXCL [USIVE]] DAN exp3 [ INCL [USIVE] | EXCL [USIVE]]

Pertimbangkan betapa mudahnya mengekspresikan WHERE DATE_FIELD BETWEEN :dt INCLUSIVE AND :dt+1 EXCLUSIVE(atau hanya WHERE DATE_FIELD BETWEEN :dt AND :dt+1 EXCL)

Mungkin ANSI SQL: 2015?


Jawaban ini adalah saran bijak.
Basil Bourque

@KevinKirkPatrick - Jawaban bagus! Saya sarankan Anda juga mencoba menemukan dokumentasi keputusan sebagai bukti objektif dari Mengapa asli.
Todd

3
Saya pribadi menyukai exp1 BETWEEN exp2 AND exp3 AND exp1 != exp3cara itu Anda bisa menjaga antara operator sehingga Anda tahu itu adalah predikat berkisar, dan predikat ketidaksetaraan memastikan bahwa itu semi terbuka.
Sentinel

@Sentinel, Bagus! Saya tidak akan mendeklarasikan diri saya sebagai orang yang dipertobatkan sebelum waktunya, tetapi saya pasti akan mengingat varian ini ketika saya berikutnya menentukan kondisi rentang tanggal. Pada blush on pertama, ia memang memiliki daya tarik linguistik yang lebih besar daripada exp1> = exp2 AND exp1 <exp3; dan jelas memecahkan masalah ANTARA dengan sama baiknya. Saya akan tertarik jika ada pengoptimal yang menunjukkan "pemahaman" yang lebih besar tentang satu variasi dari yang lain; tentu saja, tampaknya masuk akal bahwa Anda dapat menghasilkan hasil yang lebih baik dalam hal itu juga (meskipun terus terang, saya akan sangat kecewa dengan pengoptimal yang memperlakukannya secara berbeda)
KevinKirkpatrick

@KevinKirkpatrick Saya tidak pernah membuat profil mereka untuk memastikan apakah ada perbedaan, dan saya juga akan kecewa jika ada.
Sentinel

8

Baik inklusif ( a <= x <= b) dan eksklusif ( a < x < b) hampir sama-sama umum, jadi ketika membuat standar mereka hanya harus memilih satu. "Antara" dalam bahasa Inggris umum biasanya inklusif, dan pernyataan SQL dimaksudkan untuk membaca mirip dengan kalimat bahasa Inggris, jadi inklusif adalah pilihan yang masuk akal.


4
Sebenarnya penggunaan dalam bahasa Inggris bahkan lebih campur aduk saat Anda meninggalkan Half-Open. Ketika kami mengatakan "makan siang adalah antara siang dan 1 siang" kami berarti setengah terbuka di mana Anda diharapkan kembali di kelas / bekerja pada saat 13: 00: 00.000, dengan istirahat naik tetapi tidak termasuk saat pertama jam satu jam. a <= x < bsetengah terbuka.
Basil Bourque

1
@BasilBourque: Ini mungkin disebabkan oleh ketepatan yang tak terbatas - mis. Makan siang adalah antara siang dan 12: 59: 99.9999999999999 ....
Brendan

@ Brendan Ya, Anda menegaskan maksud saya. Ketepatan tak terhingga (atau ambigu) adalah salah satu masalah yang ditangani dengan menggunakan pendekatan setengah terbuka untuk menentukan rentang waktu. Intinya di sini adalah bahwa dalam percakapan bahasa Inggris kita secara intuitif menangani buka dan tutup (seperti yang disebutkan dalam jawaban ini) serta rentang setengah terbuka tanpa banyak pemikiran. Setiap pendekatan memiliki tujuan. Itulah mengapa definisi SQL ANTARA kurang optimal. Idealnya, SQL akan mengikuti saran dari KevinKirkpatrick .
Basil Bourque

2
SQL seharusnya seperti bahasa Inggris, dan meskipun inklusif dan eksklusif mungkin sama-sama umum, itu adalah bahasa query untuk analis dan pemrogram. Sebagai seorang programmer, saya pikir itu didefinisikan salah, tetapi itu tidak terlalu penting, saya hanya menghindari menggunakan "ANTARA". Bukan masalah besar.
Todd

5

Operator tidak dipanggil ∩[a,b), itu disebut BETWEEN, jadi itu jauh lebih tepat untuk semantik untuk menjadi orang-orang dari ungkapan bahasa Inggris "berada di antara" daripada yang dari predikat matematika "adalah dalam interval semi-terbuka".


Kita perlu mempertimbangkan semua aplikasi, bukan hanya aplikasi bahasa Inggris untuk set Integer. "antara 1 dan 10", "antara siang dan 1 siang", "antara 1.0 dan 5.0" (gram). "antara 5,50 dan 10,30" (dolar). Kuantitas kontinu akan secara logis (bahasa Inggris) dianggap eksklusif.
Todd

1
Masalahnya adalah bahwa BETWEENoperator tidak menggunakan semantik dari frasa bahasa Inggris "is between". Dalam bahasa Inggris "between" adalah waktu, ruang atau interval yang memisahkan berbagai hal (yaitu eksklusif ). Jika Anda mencoba menendang gol, bola harus masuk di antara tiang untuk mencetak gol. Jika Anda membentur tiang gagal melewati di antara mereka - tidak ada skor untuk Anda.
Disillusioned

1
@CraigYoung seperti yang diterima oleh jawaban yang diterima (dan saya setuju), "jika saya mengatakan" Pilih angka antara 1 dan 10 ", kebanyakan orang akan memasukkan angka 1 dan 10 [dalam kisaran kemungkinan jawaban mereka]". Dalam domain spasial saya setuju dengan Anda, tetapi untuk angka saya akan mengatakan itu berbeda. Lebih baik untuk Bahasa Inggris & Penggunaan daripada di sini!
AakashM

@ AashashM Maksud saya adalah bahwa Anda telah membuat klaim tentang bahasa Inggris yang hanya salah dengan definisi kamus dari kata "antara", untuk membenarkan semantik pemrograman. Fakta bahwa ada pemahaman umum tentang frasa "antara 1 dan 10" tidak ada hubungannya dengan makna "antara" dan lebih banyak hubungannya dengan posisi 1 dan 10 dalam sistem angka desimal. Otak manusia "auto-correct" mengabaikan bahwa "di antara" tidak termasuk titik akhir dalam kasus ini karena tampaknya konyol artinya "dari 2 hingga 9". Coba hal yang sama dengan "antara 13 dan 24". Atau bahkan "antara 0 dan 11".
Disillusioned

Antara Anda dan saya, klaim kategori tentang bahasa alami biasanya tidak aman.
AakashM
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.