Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Sisa di PostgreSQL, MS SQL Server, MySQL, dan SQLite

Masalah:

Anda ingin mencari sisa (non-negatif).

Contoh:

Dalam tabel numbers , Anda memiliki dua kolom bilangan bulat:a dan b .

a b
9 3
5 3
2 3
0 3
-2 3
-5 3
-9 3
5 -3
-5 -3
5 0
0 0

Anda ingin menghitung sisa dari pembagian a oleh b . Setiap sisa harus berupa nilai bilangan bulat non-negatif yang lebih kecil dari b .

Solusi 1 (tidak sepenuhnya benar):

SELECT
  a,
  b,
  a % b AS remainder
FROM numbers;

Hasilnya adalah:

a b sisa
9 3 0
5 3 2
2 3 2
0 3 0
-2 3 -2
-5 3 -2
-9 3 0
5 -3 2
-5 -3 -2
5 0 kesalahan
0 0 kesalahan

Diskusi:

Solusi ini bekerja dengan benar jika a adalah non-negatif. Namun, jika negatif, tidak mengikuti definisi matematika dari sisanya.

Secara konseptual, sisa adalah apa yang tersisa setelah pembagian bilangan bulat a oleh b . Secara matematis, sisa dua bilangan bulat adalah bilangan bulat tak negatif yang lebih kecil dari pembagi b . Lebih tepatnya, ini adalah bilangan r∈{0,1,...,b - 1} yang memiliki beberapa bilangan bulat k sehingga a =k * b + r.

Beginilah cara a % b bekerja untuk dividen non-negatif di kolom a :

5 = 1 * 3 + 2 , jadi sisa 5 dan 3 sama dengan 2 .

9 = 3 * 3 + 0 , jadi sisa 9 dan 3 sama dengan 0 .

5 = (-1) * (-3) + 2 , jadi sisa 5 dan -3 sama dengan 2 .

Jelas, kesalahan ditampilkan jika pembagi b adalah 0 , karena Anda tidak dapat membagi dengan 0 .

Mendapatkan sisa yang benar bermasalah ketika dividen a adalah bilangan negatif. Sayangnya, a % b dapat mengembalikan nilai negatif ketika a adalah negatif. Mis.:

-2 % 5 mengembalikan -2 kapan seharusnya mengembalikan 3 .

-5 % -3 mengembalikan -2 kapan seharusnya mengembalikan 1 .

Solusi 2 (benar untuk semua angka):

SELECT
  a,
  b,
  CASE WHEN a % b >= 0
    THEN a % b
  ELSE
    a % b + ABS(b)
  END AS remainder
FROM numbers;

Hasilnya adalah:

a b sisa
9 3 0
5 3 2
2 3 2
0 3 0
-2 3 1
-5 3 1
-9 3 0
5 -3 2
-5 -3 1
5 0 kesalahan
0 0 kesalahan

Diskusi:

Untuk menghitung sisa pembagian apa saja dua bilangan bulat (negatif atau non-negatif), Anda dapat menggunakan CASE WHEN konstruksi. Jika a % b non-negatif, sisanya hanya a % b . Jika tidak, kita perlu memperbaiki hasil yang dikembalikan oleh a % b .

Jika a % b mengembalikan nilai negatif, Anda harus menambahkan nilai absolut pembagi ke a % b . Yaitu, buat a % b + ABS(b) :

-2 % 5 mengembalikan -2 kapan seharusnya mengembalikan 3 . Anda dapat memperbaikinya dengan menambahkan 5 .

-5 % (-3) mengembalikan -2 kapan seharusnya mengembalikan 1 . Anda dapat memperbaikinya dengan menambahkan 3 .

Ketika a % b mengembalikan nilai negatif, CASE WHEN hasilnya harus a % b + ABS(b) . Ini adalah bagaimana Anda mendapatkan Solusi 2. Jika Anda membutuhkan penyegaran tentang bagaimana ABS() berfungsi, lihat buku masak Cara menghitung nilai absolut dalam SQL.

Tentu saja, jika b = 0 , Anda masih akan mendapatkan kesalahan.

Solusi 3 (benar untuk semua angka):

SELECT
  a,
  b,
  a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2 AS remainder
FROM numbers;

Hasilnya adalah:

a b sisa
9 3 0
5 3 2
2 3 2
0 3 0
-2 3 1
-5 3 1
-9 3 0
5 -3 2
-5 -3 1
5 0 kesalahan
0 0 kesalahan

Diskusi:

Ada cara lain untuk mengatasi masalah ini. Alih-alih CASE WHEN , gunakan rumus matematika satu baris yang lebih kompleks:

a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2

Dalam Solusi 2, a % b + ABS(b) dikembalikan untuk kasus ketika a % b < 0 . Perhatikan bahwa a % b + ABS(b) = a % b + ABS(b) * 1 when a % b < 0 .

Jadi, kita dapat mengalikan ABS(b) dengan ekspresi yang sama dengan 1 untuk nilai negatif a % b dan 0 untuk nilai non-negatif a % b . Sejak a % b selalu bilangan bulat, ekspresi a % b + 0.5 selalu positif untuk a % b >= 0 dan negatif untuk a % b < 0 . Anda dapat menggunakan bilangan positif apa pun yang kurang dari 1 bukannya 0.5 .

Fungsi tanda SIGN() mengembalikan 1 jika argumennya benar-benar positif, -1 jika benar-benar negatif, dan 0 jika sama dengan 0 . Namun, Anda memerlukan sesuatu yang hanya mengembalikan 0 dan 1 , bukan 1 dan -1 . Tapi jangan khawatir! Inilah cara Anda memperbaikinya:

(1 - 1) / 2 = 0

(1 - (-1)) / 2 = 1

Kemudian, ekspresi yang benar untuk mengalikan ABS(b) adalah:

(1 - SIGN(a % b + 0.5)) / 2

Jadi, seluruh rumusnya adalah:

a % b + ABS(b) * (1 - SIGN(a % b + 0.5)) / 2


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menggunakan Suka Di MySQL untuk Operasi Pencarian Menggunakan Pola

  2. Cara Membuat Daftar Tabel di MySQL dan MariaDB

  3. Python SQL – Cara menggunakan Database SQLite, MySQL, dan PostgreSQL dengan Python

  4. Bagaimana cara menghapus semua karakter numerik non-alfa dari string di MySQL?

  5. Bagaimana saya bisa mengubah batas waktu koneksi Mysql default saat menghubungkan melalui python?