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

Apakah ada cara untuk menampilkan klausa WHERE hanya untuk satu bidang di MySQL?

Sebelum MySQL 5.7, defaultnya adalah mengizinkan group by . Yang berarti Anda dapat memiliki grup dengan (yang menggunakan fungsi agregat seperti sum dan max dan count dan group_concat ) dengan kolom non-agregat lainnya (sebut saja NON AGGS ) seperti 3 tampilan pertama Anda tidak semua bagian dari group by ayat. Itu mengizinkannya tetapi hasilnya biasanya akan seperti ini:

  • Ini bekerja dengan baik karena Anda mengetahui data Anda dengan baik dan mencoba untuk mencapai

    . yang berbeda
  • Itu bekerja dengan buruk karena itu adalah snafu

Sebelum 5.7, ONLY_FULL_GROUP_BY ada tapi MATIKAN secara default.

Jadi di MySQL 5.7 muncullah ONLY_FULL_GROUP_BY default ON. Dengan demikian jika Anda mencoba grup dengan, tetapi dengan tidak semua NON AGGS di group by klausa, Anda akan mendapatkan Error.

Perhatikan masalah berikut pada 5.6 di bawah ini:

create table thing
(   col1 int not null,
    col2 int not null,
    age int not null
);
insert thing(col1,col2,age) values 
(1,2,10),
(1,3,20),
(2,3,20),
(2,2,10);

select col1,col2,max(age) from thing group by col1;
+------+------+----------+
| col1 | col2 | max(age) |
+------+------+----------+
|    1 |    2 |       20 |
|    2 |    3 |       20 |
+------+------+----------+

Yang terjadi di atas tidak semuanya NON AGGS berada di group by . Ini mengembalikan max(age) oleh col1. Tapi karena col2 tidak ada dalam group by , itu menggunakan Indeks Cluster atau Pengurutan Fisik dan membawanya, mungkin secara tidak sengaja (snafu, kesalahan), nilai yang salah untuk col2. Tergantung niat Anda atau mengetahui data Anda atau bahkan peduli. Mesinnya tidak peduli; mungkin Anda melakukannya.

Untuk menghindari kesalahan umum atau pengembalian data yang tidak disengaja ini, MySQL 5.7 mengaktifkan ONLY_FULL_GROUP_BY secara default.

Dalam kasus Anda, baris yang salah membuat hasil Anda mungkin untuk kolom 2 dan 3.

Lihat Halaman Manual berjudul Penanganan MySQL dari GROUP BY .

Contoh 2

-- drop table if exists person;
create table person
(   id int auto_increment primary key,
    firstName varchar(100) not null,
    lastName varchar(100) not null
);

-- drop table if exists fruitConsumed;
create table fruitConsumed
(   id int auto_increment primary key,
    theDate date not null,
    fruitId int not null, -- does not really matter. Say, 1=apple, 2=orange from some other table
    personId int not null,
    qty int not null
);

-- truncate table person;
insert person (firstName,lastName) values 
('Dirk','Peters'),
('Dirk','Smith'),
('Jane','Billings');

-- truncate table fruitConsumed;
insert fruitConsumed (theDate,fruitId,personId,qty) values
('2016-10-31',1,1,2),
('2016-10-31',2,1,5),
('2016-10-31',2,2,12),
('2016-11-02',2,2,3);

Pertanyaan:

select p.firstName,p.lastName,sum(fc.qty) 
from person p 
join fruitConsumed fc 
on fc.personId=p.id 
group by p.firstName,p.lastName; 
+-----------+----------+-------------+
| firstName | lastName | sum(fc.qty) |
+-----------+----------+-------------+
| Dirk      | Peters   |           7 |
| Dirk      | Smith    |          15 |
+-----------+----------+-------------+

Di atas berfungsi dengan baik di MySQL 5.6 dan 5.7 terlepas dari pengaturan untuk ONLY_FULL_GROUP_BY

sekarang pertimbangkan

select p.firstName,p.lastName,sum(fc.qty) 
from person p 
join fruitConsumed fc 
on fc.personId=p.id 
group by p.firstName; 

+-----------+----------+-------------+
| firstName | lastName | sum(fc.qty) |
+-----------+----------+-------------+
| Dirk      | Peters   |          22 |
+-----------+----------+-------------+

Hal di atas sering dapat diterima di MySQL 5.6 tanpa ONLY_FULL_GROUP_BY diaktifkan dan gagal pada 5.7 dengan ONLY_FULL_GROUP_BY diaktifkan (kesalahan 1055). Output di atas pada dasarnya adalah omong kosong. Tapi di bawah ini dijelaskan sedikit:

Kita tahu bahwa Dirk, seorang Dirk, hanya satu Dirk, adalah satu-satunya yang selamat dari inner join. Ada 2 Dirk. Tapi karena group by p.firstName , kita hanya memiliki satu Dirk. Kami membutuhkan lastName . Karena ketidaksesuaian dengan
Standar SQL, MySQL dapat mengizinkannya dengan ONLY_FULL_GROUP_BY matikan. Jadi itu hanya memilih nama belakang lama. Nah, yang pertama ditemukan, dan itu ada di cache atau yang ada di urutan fisik.

Dan itu pergi dengan Peters. Jumlah jumlah buah adalah untuk semua Dirks.

Jadi jika Anda membuat kode seperti ini, kode non-ONLY_FULL_GROUP_BY yang tidak sesuai memberi Anda omong kosong.

Dan seperti yang dinyatakan, MySQL 5.7 dikirimkan secara default untuk tidak mengizinkan ini. Tapi itu bisa diubah dengan cara lama jika Anda mau.

Sangat disarankan agar Anda memperbaiki kueri dan meninggalkan ONLY_FULL_GROUP_BY saat diaktifkan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menyortir Di MySQL Menggunakan Order By Clause

  2. ROW_NUMBER() di MySQL

  3. Apa cara terbaik untuk menyimpan file media di database?

  4. Apakah ada cara untuk menampilkan klausa WHERE hanya untuk satu bidang di MySQL?

  5. Bagaimana cara membuat pengguna MySQL hanya-baca?