Rumah  >  Soal Jawab  >  teks badan

Pertanyaan SQL untuk memilih hanya baris dengan nilai lajur maksimum

<p>Saya mempunyai jadual dokumen (di sini ialah versi ringkas): </p> <table class="s-table"> <kepala> <tr> <th>id</th> <th>rev</th> <th>kandungan</th> </tr> </kepala> <tbody> <tr> <td>1</td> <td>1</td> <td>...</td> </tr> <tr> <td>2</td> <td>1</td> <td>...</td> </tr> <tr> <td>1</td> <td>2</td> <td>...</td> </tr> <tr> <td>1</td> <td>3</td> <td>...</td> </tr> </tbody> </table> <p>Bagaimana untuk memilih satu baris setiap id dan hanya memilih rev terbesar? </p><p> Berdasarkan data di atas, hasilnya harus mengandungi dua baris: <code>[1, 3, ...]</code> dan <code>[2, ​​​​1, ..]</code> ;. Saya menggunakan <strong><em>MySQL</em></strong>. </p> <p>Pada masa ini, saya menggunakan semakan dalam <kod>semasa</kod> gelung untuk mengesan dan menulis ganti rev lama dalam set hasil. Tetapi adakah ini satu-satunya cara untuk mencapai hasil? Adakah tiada penyelesaian untuk <strong>SQL</strong>? </p>
P粉662614213P粉662614213425 hari yang lalu364

membalas semua(2)saya akan balas

  • P粉909476457

    P粉9094764572023-08-22 12:49:52

    Saya lebih suka menggunakan kod sesedikit mungkin...

    Anda boleh menggunakan IN untuk mencapai Cuba ini:

    SELECT * 
    FROM t1 WHERE (id,rev) IN 
    ( SELECT id, MAX(rev)
      FROM t1
      GROUP BY id
    )

    Pada pendapat saya, ini lebih mudah... lebih mudah dibaca dan diselenggara.

    balas
    0
  • P粉287345251

    P粉2873452512023-08-22 09:59:35

    Sepintas lalu...

    Anda hanya perlu menggunakan klausa dengan MAX聚合函数的GROUP BY:

    SELECT id, MAX(rev)
    FROM YourTable
    GROUP BY id

    Perkara tidak pernah semudah itu, bukan?

    Saya baru perasan bahawa anda juga memerlukan content lajur.

    Ini adalah masalah yang sangat biasa dalam SQL: cari seluruh baris data dengan nilai maksimum dalam lajur berdasarkan pengecam kumpulan tertentu. Saya telah banyak mendengar soalan ini dalam kerjaya saya. Sebenarnya, ini adalah salah satu soalan yang saya jawab semasa temuduga teknikal di tempat kerja saya sekarang.

    Soalan ini sebenarnya sangat biasa sehingga komuniti Stack Overflow mencipta teg khusus untuk menangani soalan jenis ini: .

    Pada asasnya, anda mempunyai dua cara untuk menyelesaikan masalah ini:

    Sertai menggunakan group-identifier, max-value-in-groupsubquery

    mudah

    Dalam pendekatan ini anda mula-mula menemui group-identifier, max-value-in-group(已经在上面解决了)。然后,你将你的表与子查询进行连接,使用group-identifiermax-value-in-group dalam subkueri (sudah diselesaikan di atas). Anda kemudian sertai jadual anda dengan subkueri, menggunakan

    dan max-value-in-group untuk equijoin:

    SELECT a.id, a.rev, a.contents
    FROM YourTable a
    INNER JOIN (
        SELECT id, MAX(rev) rev
        FROM YourTable
        GROUP BY id
    ) b ON a.id = b.id AND a.rev = b.rev

    Gunakan sambungan sendiri dan laraskan keadaan sambungan dan keadaan penapisan

    group-identifierDalam pendekatan ini, anda melakukan cantuman kiri jadual dengan dirinya sendiri. Equijoining dilakukan pada

    . Kemudian, ada dua langkah bijak:
    1. Syarat sambungan kedua ialah nilai di sebelah kiri kurang daripada nilai di sebelah kanan
    2. NULL(记住,这是一个LEFT JOIN)。然后,我们过滤连接结果,只显示右侧为NULLApabila anda melakukan langkah 1, baris yang sebenarnya mempunyai nilai terbesar akan mempunyai baris
    3. di sebelah kanan.

    Jadi anda akan mendapat:

    SELECT a.*
    FROM YourTable a
    LEFT OUTER JOIN YourTable b
        ON a.id = b.id AND a.rev < b.rev
    WHERE b.id IS NULL;

    Kesimpulan

    Hasil yang diperolehi oleh kedua-dua kaedah ini adalah sama.

    group-identifier有两行具有max-value-in-groupJika terdapat dua baris dengan nilai-maks-dalam-kumpulan untuk

    , kedua-dua kaedah akan memasukkan kedua-dua baris dalam hasil.

    Kedua-dua kaedah ini serasi dengan SQL ANSI, jadi tidak kira apa "rasa" RDBMS yang anda suka, anda boleh menggunakannya.

    Kedua-dua kaedah juga mesra prestasi, tetapi situasi sebenar anda mungkin berbeza (RDBMS, struktur pangkalan data, indeks, dll.). Jadi apabila anda memilih salah satu kaedah ini, lakukan penanda aras

    . Dan pastikan anda memilih kaedah yang paling sesuai untuk anda. 🎜

    balas
    0
  • Batalbalas