Saya memiliki 2 tabel di database saya. Satu untuk pesanan, dan satu untuk perusahaan.
Pesanan memiliki struktur ini:
OrderID | attachedCompanyIDs
------------------------------------
1 1,2,3
2 2,4
Dan Perusahaan memiliki struktur ini:
CompanyID | name
--------------------------------------
1 Company 1
2 Another Company
3 StackOverflow
4 Nothing
Untuk mendapatkan nama perusahaan pesanan, saya dapat melakukan kueri seperti:
SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)
Kueri itu berfungsi dengan baik, tetapi kueri berikut tidak.
SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)
Mengapa kueri pertama berfungsi tetapi bukan yang kedua?
Kueri pertama kembali:
name
---------------
Company 1
Another Company
StackOverflow
Kueri kedua hanya mengembalikan:
name
---------------
Company 1
Mengapa ini, mengapa permintaan pertama mengembalikan semua perusahaan, tetapi permintaan kedua hanya mengembalikan yang pertama?
Jawaban:
attachedCompanyIDs
adalah nilai skalar yang dilemparkan ke dalamINT
(tipecompanyID
).Para pemain hanya mengembalikan angka hingga non-digit pertama (koma dalam kasing Anda).
Jadi,
Di
PostgreSQL
, Anda bisa memasukkan string ke array (atau menyimpannya sebagai array di tempat pertama):dan ini bahkan akan menggunakan indeks
companyID
.Sayangnya, ini tidak berfungsi
MySQL
karena yang terakhir tidak mendukung array.Anda mungkin menemukan artikel ini menarik (lihat
#2
):Memperbarui:
Jika ada beberapa batasan yang masuk akal pada jumlah nilai dalam daftar yang dipisahkan koma (katakanlah, tidak lebih dari
5
), maka Anda dapat mencoba menggunakan kueri ini:sumber
FIND_IN_SET
berfungsi, tetapi tidak menggunakan indeks, dan mungkin lambat dengan banyak info di tabel Perusahaan.pos
item dari awalCVS
dan melemparkan sisanya ke integer.10 things in MySQL (that won’t work as expected)
CROSS JOIN
? Bukankah semuanya sama di MySQL?attachCompanyIDs adalah satu string besar, jadi mysql mencoba untuk menemukan perusahaan dalam gips untuk integer
ketika Anda gunakan di mana
jadi jika comapnyid = 1:
ini benar kembali
tetapi jika nomor 1 tidak di tempat pertama
pengembaliannya salah
sumber
Untuk mendapatkan nama semua perusahaan terkait, tidak didasarkan pada ID tertentu.
sumber
karena kueri kedua mencari baris dengan id 1 ATAU 2 ATAU 3, kueri pertama mencari salah satu dari nilai yang dibatasi koma yang ada di companyID,
dan masalah lain di sini adalah Anda tidak bergabung dengan tabel pada kunci umum di mana Anda sehingga Anda akan mendapatkan mutasi baris yang = count (table1) * count (table2);
Masalah Anda benar-benar ada pada bagian 2 dari jawaban saya. (dengan permintaan kedua Anda)
sumber
Biarkan saya menjelaskan kapan harus menggunakan FIND_IN_SET dan Kapan menggunakan IN.
Mari kita ambil tabel A yang memiliki kolom bernama "aid", "aname". Mari kita ambil tabel B yang memiliki kolom bernama "bid", "bname", "aids".
Sekarang ada nilai dummy di Tabel A dan Tabel B seperti di bawah ini.
Tabel A
aname bantuan
1 Apple
2 pisang
3 Mangga
Tabel B
bantu tawaran bname
1 Apple 1,2
2 Pisang 2,1
3 Mangga 3,1,2
Kasus1: jika Anda ingin mendapatkan catatan itu dari tabel b yang memiliki 1 nilai hadir di kolom bantu maka Anda harus menggunakan FIND_IN_SET.
Kueri: pilih * dari A JOIN B ON FIND_IN_SET (A.aid, b.aids) di mana A.aid = 1;
Kasus2: jika Anda ingin mendapatkan catatan-catatan dari tabel a yang memiliki nilai 1 ATAU 2 ATAU 3 hadir di kolom bantuan maka Anda harus menggunakan IN.
Pertanyaan: pilih * dari A JOIN B ON A.aid IN (b.aids);
Sekarang terserah Anda bahwa apa yang Anda butuhkan melalui permintaan mysql.
sumber
sumber