Ekspresi apa pun dalam SQL harus merujuk kolom hanya dalam satu baris (kecuali subkueri).
Sebuah JOIN
dapat digunakan untuk membuat dua baris berbeda menjadi satu baris dari kumpulan hasil.
Jadi Anda dapat membandingkan nilai pada baris yang berbeda dengan melakukan self-join. Berikut adalah contoh yang menunjukkan penggabungan setiap baris ke setiap baris lain yang terkait dengan klien yang sama (tidak termasuk penggabungan baris ke dirinya sendiri):
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
Sekarang Anda dapat menulis ekspresi yang membandingkan kolom. Misalnya, untuk membatasi kueri di atas ke kueri di mana field1 berbeda:
SELECT c1.*, c2.*
FROM client c1
JOIN client c2 ON (c1.clientID = c2.clientID AND c1.id <> c2.id)
WHERE c1.field1 <> c2.field1;
Anda tidak menentukan jenis perbandingan apa yang perlu Anda buat, jadi saya akan menyerahkannya kepada Anda. Intinya adalah bahwa secara umum, Anda dapat menggunakan self-join untuk membandingkan baris dalam tabel tertentu.
Kembali komentar dan klarifikasi Anda:Oke, jadi "perbedaan" Anda bukan hanya berdasarkan nilai tetapi berdasarkan posisi ordinal baris. Ingat bahwa database relasional tidak memiliki konsep nomor baris, mereka hanya memiliki urutan baris sehubungan dengan beberapa urutan yang harus Anda tentukan dalam ORDER BY
ayat. Jangan bingung "id
" pseudokey dengan nomor baris, angka-angka tersebut ditetapkan sebagai peningkatan monoton hanya karena kebetulan implementasinya.
Di MySQL, Anda dapat memanfaatkan variabel yang ditentukan pengguna untuk mencapai efek yang Anda cari. Pesan kueri dengan clientId
dan kemudian dengan id
, dan melacak nilai per kolom dalam variabel pengguna MySQL. Ketika nilai dalam baris saat ini berbeda dari nilai dalam variabel, lakukan sorotan apa pun yang akan Anda lakukan. Saya akan menunjukkan contoh untuk satu bidang:
SET @clientid = -1, @field1 = '';
SELECT id, clientId, field1, @clientid, @field1,
IF(@clientid <> clientid,
((@clientid := clientid) AND (@field1 := field1)) = NULL,
IF (@field1 <> field1,
(@field1 := field1),
NULL
)
) AS field1_changed
FROM client c
ORDER BY clientId, id;
Perhatikan bahwa solusi ini tidak terlalu berbeda dari hanya memilih semua baris dengan SQL biasa, dan melacak nilai dengan variabel aplikasi saat Anda mengambil baris.