Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Formulasi subquery kompleks MySQL

Saya setuju dengan Strawberry tentang skema. Kita bisa mendiskusikan ide-ide untuk kinerja yang lebih baik dan sebagainya. Tapi inilah pendapat saya tentang cara mengatasi ini setelah beberapa obrolan dan perubahan pada pertanyaan.

Perhatikan di bawah perubahan data untuk menangani berbagai kondisi batas yang mencakup buku tanpa gambar di tabel itu, dan tie-break. Arti tie-break menggunakan max(upvotes) . OP mengubah pertanyaan beberapa kali dan menambahkan kolom baru di tabel gambar.

Pertanyaan yang dimodifikasi menjadi pengembalian 1 baris per buku. Gores itu, selalu 1 baris per buku meskipun tidak ada gambar. Info gambar yang dikembalikan adalah yang memiliki upvotes maksimal.

Tabel buku

create table books 
(   id int primary key, 
    name varchar(1000), 
    releasedate date, 
    purchasecount int
) ENGINE=InnoDB;

insert into books values(1,"fool","1963-12-18",456);
insert into books values(2,"foo","1933-12-18",11);
insert into books values(3,"fooherty","1943-12-18",77);
insert into books values(4,"eoo","1953-12-18",678);
insert into books values(5,"fooe","1973-12-18",459);
insert into books values(6,"qoo","1983-12-18",500);

Perubahan Data dari pertanyaan awal.

Terutama upvotes . yang baru kolom.

Di bawah ini termasuk baris tie-break yang ditambahkan.

create table images 
(   bookid int, 
    poster varchar(150) primary key, 
    bucketid int, 
    upvotes int -- a new column introduced by OP
) ENGINE=InnoDB;

insert into images values (1,"xxx",12,27);
insert into images values (5,"pqr",11,0);
insert into images values (5,"swt",11,100);
insert into images values (2,"yyy",77,65);
insert into images values (1,"qwe",111,69);
insert into images values (1,"blah_blah_tie_break",111,69);
insert into images values (3,"qwqqe",14,81);
insert into images values (1,"qqawe",8,45);
insert into images values (2,"z",81,79);

Visualisasi Tabel Turunan

Ini hanya untuk membantu memvisualisasikan bagian dalam dari kueri akhir. Ini menunjukkan gotcha untuk situasi tie-break, sehingga rownum variabel. Variabel itu direset menjadi 1 setiap kali bookid berubah jika tidak maka akan bertambah. Pada akhirnya (permintaan terakhir kami) kami hanya ingin rownum=1 baris sehingga maksimal 1 baris dikembalikan per buku (jika ada).

Permintaan Akhir

select b.id,b.purchasecount,xDerivedImages2.poster,xDerivedImages2.bucketid
from books b
left join
(   select i.bookid,i.poster,i.bucketid,i.upvotes,
    @rn := if(@lastbookid = i.bookid, @rn + 1, 1) as rownum,
    @lastbookid := i.bookid as dummy
    from 
    (   select bookid,max(upvotes) as maxup
        from images
        group by bookid
    ) xDerivedImages
    join images i
    on i.bookid=xDerivedImages.bookid and i.upvotes=xDerivedImages.maxup
    cross join (select @rn:=0,@lastbookid:=-1) params
    order by i.bookid
) xDerivedImages2
on xDerivedImages2.bookid=b.id and xDerivedImages2.rownum=1
order by b.purchasecount desc
limit 10

Hasil

+----+---------------+---------------------+----------+
| id | purchasecount | poster              | bucketid |
+----+---------------+---------------------+----------+
|  4 |           678 | NULL                |     NULL |
|  6 |           500 | NULL                |     NULL |
|  5 |           459 | swt                 |       11 |
|  1 |           456 | blah_blah_tie_break |      111 |
|  3 |            77 | qwqqe               |       14 |
|  2 |            11 | z                   |       81 |
+----+---------------+---------------------+----------+

Pentingnya cross join hanya untuk memperkenalkan dan menetapkan nilai awal untuk 2 variabel. Itu saja.

Hasilnya adalah sepuluh buku teratas dalam urutan purchasecount dengan info dari images jika ada (jika tidak NULL ) untuk gambar yang paling banyak dipilih. Gambar yang dipilih menghormati aturan tie-break memilih yang pertama seperti yang disebutkan di atas di bagian Visualisasi dengan rownum .

Pemikiran Terakhir

Saya menyerahkannya kepada OP untuk dijepit di where yang sesuai klausa di akhir karena data sampel yang diberikan tidak memiliki nama buku yang berguna untuk dicari. Bagian itu sepele. Oh, dan lakukan sesuatu tentang skema untuk lebar besar kunci utama Anda. Tapi itu di luar topik saat ini.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sisipkan kueri, periksa apakah ada catatan - Jika tidak, Sisipkan

  2. Masukkan data ke tabel MySQL dari skrip Python

  3. R dan MySQL - memeriksa apakah ada baris dalam tabel sebelum menulisnya menggunakan dbWriteTable()

  4. Memfilter file log menggunakan COUNT, GROUP BY, ORDER BY MAX

  5. json_encode untuk kueri mysql mengembalikan beberapa kolom nol dari beberapa baris, tetapi kolomnya tidak nol