Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy istnieje sposób na pokazanie klauzuli WHERE tylko dla jednego pola w MySQL?

Przed MySQL 5.7 domyślnie zezwalało na nie PEŁNE group by . Co oznacza, że ​​możesz mieć grupę według (która używa funkcji agregujących, takich jak sum i max i count i group_concat ) z innymi kolumnami niezagregowanymi (nazwijmy je NON AGGS ) jak Twoje pierwsze 3 pokazane nie wszystkie część twojej group by klauzula. Pozwoliło na to, ale wyniki zwykle wyglądały tak:

  • Udało się to świetnie, ponieważ dobrze znasz swoje dane i starasz się osiągnąć wyraźny

  • Udało się okropnie, bo to było snafu

Przed wersją 5.7 ONLY_FULL_GROUP_BY istniał, ale był domyślnie WYŁĄCZONY.

Tak więc w MySQL 5.7 pojawia się ONLY_FULL_GROUP_BY domyślnie WŁ. Jako takie, jeśli próbujesz grupować, ale z nie wszystkimi NON AGGS w grupie group by klauzula, otrzymasz błąd.

Rozważ następujący problem w 5.6 poniżej:

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

To, co dzieje się powyżej, to nie tylko NON AGGS są w group by . Zwraca max(age) przez col1. Ale ponieważ col2 nie był w grupie group by , użył Indeksu Klastrów lub Porządku Fizycznego i przyniósł mu, być może nieumyślnie (snafu, pomyłka), niewłaściwą wartość dla col2. W zależności od twoich intencji lub znajomości danych, a nawet troski. Silnik nie przejmował się; być może tak.

Aby uniknąć tych typowych błędów lub nieumyślnego zwracania danych, MySQL 5.7 włącza ONLY_FULL_GROUP_BY domyślnie.

W Twoim przypadku nieprawidłowe wiersze składają się na wyniki prawdopodobnie w kolumnach 2 i 3.

Zobacz stronę podręcznika zatytułowaną Obsługa MySQL dla GROUP BY .

Przykład 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);

Zapytanie:

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

Powyższe działa świetnie na MySQL 5.6 i 5.7 niezależnie od ustawienia dla ONLY_FULL_GROUP_BY

teraz rozważ

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

Powyższe jest często akceptowalne w MySQL 5.6 bez ONLY_FULL_GROUP_BY włączone i nie działa w wersji 5.7 z ONLY_FULL_GROUP_BY włączone (błąd 1055). Powyższe dane wyjściowe są w zasadzie bełkotem. Ale poniżej jest to nieco wyjaśnione:

Wiemy, że Dirk, Dirk, tylko jeden Dirk, jest jedynym, który przetrwał wewnętrzne połączenie. Jest 2 sztyletów. Ale z powodu group by p.firstName , zostaje nam tylko jeden Dirk. Potrzebujemy lastName . Ze względu na niezgodność
standardu SQL, MySQL może na to pozwolić z ONLY_FULL_GROUP_BY wyłączony. Więc po prostu wybiera stare nazwisko. Cóż, pierwszy, który znajdzie, i to albo w pamięci podręcznej, albo ten w porządku fizycznym.

I poszło z Petersem. Suma liczby owoców dotyczy wszystkich Dirków.

Więc jeśli kodujesz w ten sposób, niezgodny kod niezgodny ONLY_FULL_GROUP_BY daje bełkot.

Jak już wspomniano, statki MySQL 5.7 domyślnie nie zezwalały na to. Ale można to zmienić w stary sposób, jeśli wybierzesz.

Zdecydowanie zaleca się poprawienie zapytań i pozostawienie ONLY_FULL_GROUP_BY jako włączone.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Python:użyć mysqldb do zaimportowania tabeli MySQL jako słownika?

  2. Jak przyznać użytkownikowi uprawnienia dostępu zdalnego do serwera mysql?

  3. MINUTE() Przykłady – MySQL

  4. Użyj rozszerzeń przestrzennych MySQL, aby wybrać punkty wewnątrz okręgu

  5. Eksportuj i importuj wszystkie bazy danych MySQL jednocześnie