Saya punya tabel mysql sederhana:
CREATE TABLE IF NOT EXISTS `pers` (
`persID` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(35) NOT NULL,
`gehalt` int(11) NOT NULL,
`chefID` int(11) DEFAULT NULL,
PRIMARY KEY (`persID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);
Saya mencoba menjalankan pembaruan berikut, tetapi saya hanya mendapatkan kesalahan 1093:
UPDATE pers P
SET P.gehalt = P.gehalt * 1.05
WHERE (P.chefID IS NOT NULL
OR gehalt <
(SELECT (
SELECT MAX(gehalt * 1.05)
FROM pers MA
WHERE MA.chefID = MA.chefID)
AS _pers
))
Saya mencari kesalahan dan menemukan dari halaman berikut mysql http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html , tetapi tidak membantu saya.
Apa yang harus saya lakukan untuk memperbaiki kueri sql?
sql
mysql
mysql-error-1093
CSchulz
sumber
sumber
Jawaban:
Masalahnya adalah MySQL, untuk alasan apa pun yang tidak masuk akal, tidak memungkinkan Anda untuk menulis pertanyaan seperti ini:
Artinya, jika Anda melakukan
UPDATE
/INSERT
/DELETE
di atas meja, Anda tidak dapat referensi tabel yang dalam inner query (Anda dapat namun referensi field dari yang tabel luar ...)Solusinya adalah mengganti instance
myTable
dalam sub-kueri dengan(SELECT * FROM myTable)
, seperti iniIni tampaknya menyebabkan bidang yang diperlukan disalin secara implisit ke tabel sementara, jadi itu dibolehkan.
Saya menemukan solusi ini di sini . Catatan dari artikel itu:
sumber
T
dan(SELECT * FROM T)
sepenuhnya setara. Mereka adalah hubungan yang sama. Karena itu, ini adalah pembatasan sewenang-wenang dan tidak waras. Lebih khusus, ini merupakan solusi untuk memaksa MySQL melakukan sesuatu yang jelas dapat dilakukan, tetapi karena alasan tertentu ia tidak dapat menguraikan dalam bentuk yang lebih sederhana.DELETE FROM t WHERE tableID NOT IN (SELECT viewID FROM t_view);
Saya juga merekomendasikan menjalankanOPTIMIZE TABLE t;
setelahnya untuk mengurangi ukuran tabel.Anda dapat membuatnya dalam tiga langkah:
...
atau
sumber
CREATE TABLE
pernyataan - saya harap penulis mengetahui hal ini. Namun, apakah ini satu-satunya solusi? Atau bisakah kueri ditulis ulang dengan subkueri atau gabungan? Dan mengapa (tidak) melakukan itu?UPDATE Pers P
membacaUPDATE pers P
?CREATE TABLE AS SELECT
memberikan kinerja yang mengerikan?Di Mysql, Anda tidak dapat memperbarui satu tabel dengan membuat subquery tabel yang sama.
Anda dapat memisahkan kueri dalam dua bagian, atau melakukannya
sumber
SELECT ... SET
? Saya belum pernah mendengar tentang ini.AS B
pada referensi keduaTABLE_A
. jawaban dalam contoh yang paling banyak dipilih dapat disederhanakan menggunakanAS T
alih-alih berpotensi tidak efisienFROM (SELECT * FROM myTable) AS something
, yang untungnya kueri pengoptimal biasanya menghilangkan tetapi mungkin tidak selalu melakukannya.Buat tabel sementara (tempP) dari subquery
Saya telah memperkenalkan nama yang terpisah (alias) dan memberikan nama baru ke kolom 'persID' untuk tabel sementara
sumber
SELECT ( SELECT MAX(gehalt * 1.05)..
- yang pertamaSELECT
tidak memilih kolom apa pun.Sederhana saja. Misalnya, alih-alih menulis:
kamu harus menulis
atau serupa.
sumber
Pendekatan yang diposting oleh BlueRaja lambat saya memodifikasinya karena saya gunakan untuk menghapus duplikat dari tabel. Dalam kasus ini membantu siapa saja dengan Kueri Asli tabel besar
Ini membutuhkan lebih banyak waktu:
Solusi lebih cepat
sumber
Sama seperti referensi, Anda juga dapat menggunakan Variabel Mysql untuk menyimpan hasil sementara, misalnya:
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
sumber
Jika Anda mencoba membaca fieldA dari tableA dan menyimpannya di fieldB di tabel yang sama, ketika fieldc = fieldd Anda mungkin ingin mempertimbangkan ini.
Kode di atas menyalin nilai dari fieldA ke fieldB ketika kondisi-bidang memenuhi kondisi Anda. ini juga berfungsi di ADO (mis. akses)
sumber: mencoba sendiri
sumber
MariaDB telah mengangkat ini mulai dari 10.3.x (baik untuk
DELETE
danUPDATE
):DBFiddle MariaDB 10.2 - Kesalahan
DBFiddle MariaDB 10.3 - Sukses
sumber
Solusi lain termasuk menggunakan SELECT DISTINCT atau LIMIT dalam subquery, meskipun ini tidak eksplisit dalam efeknya pada materialisasi. ini bekerja untuk saya
seperti yang disebutkan dalam MySql Doc
sumber
MySQL tidak mengizinkan memilih dari tabel dan memperbarui dalam tabel yang sama pada saat yang sama Tapi selalu ada solusinya :)
Ini tidak berfungsi >>>>
Tapi ini berhasil >>>>
sumber