Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Có cách nào để hiển thị mệnh đề WHERE chỉ cho một trường trong MySQL không?

Trước MySQL 5.7, mặc định là cho phép nhóm group by . Có nghĩa là bạn có thể có một nhóm theo (sử dụng các hàm tổng hợp như summaxcountgroup_concat ) với các cột không được tổng hợp khác (hãy gọi chúng là NON AGGS ) như 3 đầu tiên của bạn được hiển thị không phải tất cả một phần của nhóm group by mệnh đề. Nó cho phép nó nhưng kết quả thường sẽ diễn ra như thế này:

  • Nó hoạt động tốt vì bạn biết rõ dữ liệu của mình và đang cố gắng đạt được sự khác biệt

  • Nó hoạt động tệ hại bởi vì nó là một snafu

Trước ngày 5.7, ONLY_FULL_GROUP_BY tồn tại nhưng nó đã bị TẮT theo mặc định.

Vì vậy, trong MySQL 5.7 cùng với ONLY_FULL_GROUP_BY mặc định là BẬT. Như vậy nếu bạn cố gắng một nhóm theo, nhưng với không phải tất cả NON AGGS trong nhóm group by , bạn sẽ gặp lỗi.

Hãy xem xét vấn đề sau trong 5.6 dưới đây:

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 |
+------+------+----------+

Những gì xảy ra ở trên không phải là tất cả NON AGGS nằm trong nhóm group by . Nó trả về (tuổi) tối đa bằng col1. Nhưng kể từ khi col2 không có trong nhóm group by , nó đã sử dụng Chỉ mục cụm hoặc Thứ tự vật lý và vô tình có lẽ (một lỗi, một sai lầm), giá trị sai cho col2. Tùy thuộc vào ý định của bạn hoặc biết dữ liệu của bạn hoặc thậm chí quan tâm. Động cơ không quan tâm; có lẽ bạn làm.

Để tránh những lỗi thường gặp này hoặc việc trả về dữ liệu không cố ý, MySQL 5.7 bật ONLY_FULL_GROUP_BY theo mặc định.

Trong trường hợp của bạn, các hàng sai đang tạo nên kết quả của bạn có lẽ cho cột 2 và 3.

Xem Trang hướng dẫn có tên Xử lý MySQL của GROUP BY .

Ví dụ 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);

Truy vấn:

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 |
+-----------+----------+-------------+

Phần trên hoạt động tốt trên MySQL 5.6 và 5.7 bất kể cài đặt cho ONLY_FULL_GROUP_BY

bây giờ hãy xem xét

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 |
+-----------+----------+-------------+

Ở trên thường được chấp nhận trên MySQL 5.6 mà không có ONLY_FULL_GROUP_BY được bật và không thành công vào ngày 5.7 với ONLY_FULL_GROUP_BY đã bật (lỗi 1055). Kết quả trên về cơ bản là vô nghĩa. Nhưng dưới đây nó được giải thích phần nào:

Chúng ta biết rằng Dirk, một Dirk, chỉ một Dirk, là người duy nhất sống sót sau cuộc tham gia bên trong. Có 2 Dirks. Nhưng vì nhóm group by p.firstName , chúng ta chỉ còn lại một Dirk. Chúng tôi cần một lastName . Do không tuân theo
Tiêu chuẩn SQL, MySQL có thể cho phép điều này với ONLY_FULL_GROUP_BY đã tắt. Vì vậy, nó chỉ chọn bất kỳ LastName cũ nào. Chà, cái đầu tiên nó tìm thấy và cái đó nằm trong bộ nhớ cache hoặc cái trong thứ tự vật lý.

Và nó đã đi cùng với Peters. Tổng số lượng trái cây dành cho tất cả các Dirks.

Vì vậy, nếu bạn viết mã như thế này, ONLY_FULL_GROUP_BY không tuân thủ cho bạn vô nghĩa.

Và như đã nêu, MySQL 5.7 được mặc định không cho phép điều này. Nhưng nó có thể điều chỉnh theo cách cũ nếu bạn chọn.

Bạn nên sửa các truy vấn của mình và để lại ONLY_FULL_GROUP_BY như đã được kích hoạt.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql chọn từ n hàng cuối cùng

  2. Lỗi MySQL 1264:giá trị ngoài phạm vi cho cột

  3. Xóa truy vấn không hoạt động trong mysql

  4. Mac OS X - EnvironmentError:không tìm thấy mysql_config

  5. MySQL:Giao dịch so với Bảng khóa