Rumah > Soal Jawab > teks badan
P粉5187995572023-08-21 13:24:03
Penyelesaian yang betul ialah:
SELECT o.* FROM `Persons` o # 'o' from 'oldest person in group' LEFT JOIN `Persons` b # 'b' from 'bigger age' ON o.Group = b.Group AND o.Age < b.Age WHERE b.Age is NULL # bigger age not found
Ia akan sepadan dengan satu atau lebih baris dalam o
中的每一行与具有相同Group
列值和较大Age
列值的b
中的所有行进行匹配。任何o
中的行如果在Age
列中没有其组中的最大值,则会与b
.
LEFT JOIN
使其将组中的最年长的人(包括那些独自一人的人)与来自b
的一行NULL
Buat perlawanan ('Tiada sesiapa yang lebih tua dalam kumpulan').
Menggunakan INNER JOIN
akan menyebabkan garisan ini tidak sepadan dan ia akan diabaikan.
WHERE
子句仅保留从b
中提取的字段中具有NULL
OK. Mereka adalah yang paling tua dalam setiap kumpulan.
Penyelesaian ini dan banyak lagi diterangkan secara terperinci dalam buku SQL Antipatterns Jilid 1: Mengelakkan Perangkap Pengaturcaraan Pangkalan Data.
P粉7416783852023-08-21 12:41:11
Terdapat cara yang sangat mudah untuk melakukan ini dalam mysql:
select * from (select * from mytable order by `Group`, age desc, Person) x group by `Group`
Kaedah ini berfungsi kerana dalam mysql, anda boleh bukan mengagregat bukan kumpulan mengikut lajur, dalam kes ini mysql hanya mengembalikan baris pertama. Penyelesaiannya adalah untuk mengisih data terlebih dahulu dalam susunan yang anda mahu dan kemudian kumpulan mengikut lajur yang anda mahu.
Anda mengelakkan masalah subkueri kompleks yang cuba mencari max()
dsb., dan juga mengelakkan masalah mengembalikan berbilang baris apabila terdapat berbilang baris dengan nilai maksimum yang sama (jawapan lain melakukan ini).
Nota: Ini adalah penyelesaian hanya untuk mysql. Semua pangkalan data lain yang saya tahu akan membuang ralat sintaks SQL dengan mesej ralat "Lajur bukan agregat tidak disenaraikan dalam kumpulan mengikut klausa" atau sesuatu yang serupa. Oleh kerana penyelesaian ini menggunakan tidak berdokumen gelagat, orang yang lebih berhemat mungkin mahu memasukkan ujian untuk memastikan ia masih berfungsi jika versi MySQL akan datang mengubah tingkah laku ini.
Mulai versi 5.7, sql-mode
设置默认包含ONLY_FULL_GROUP_BY
, jadi untuk ini berfungsi, anda mesti tidak menggunakan pilihan ini (edit fail pilihan pelayan untuk mengalih keluar tetapan ini).