Mysql
 sql >> Database >  >> RDS >> Mysql

C'è un modo per mostrare una clausola WHERE solo per un campo in MySQL?

Prima di MySQL 5.7 l'impostazione predefinita era di consentire group by non FULL . Ciò significa che puoi avere un gruppo per (che utilizza funzioni aggregate come sum e max e count e group_concat ) con altre colonne non aggregate (chiamiamola NON AGGS ) come i primi 3 mostrati non tutti parte del tuo group by clausola. Lo consentiva, ma i risultati in genere funzionavano in questo modo:

  • Ha funzionato benissimo perché conosci bene i tuoi dati e stai cercando di ottenere un risultato distinto

  • Ha funzionato male perché è stato un pasticcio

Prima della 5.7, ONLY_FULL_GROUP_BY esisteva ma era disattivato per impostazione predefinita.

Quindi in MySQL 5.7 arriva il ONLY_FULL_GROUP_BY impostato su ON. In quanto tale, se tenti un gruppo con, ma con non tutti il NON AGGS nel group by clausola, otterresti un errore.

Considera il seguente problema in 5.6 di seguito:

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

Quello che succede sopra non è tutto il NON AGGS sono nel group by . Restituisce la max(età) di col1. Ma poiché col2 non era nel group by , ha usato il Cluster Index o Physical Ordering e gli ha portato, forse inavvertitamente (un pasticcio, un errore), il valore sbagliato per col2. A seconda delle tue intenzioni o della conoscenza dei tuoi dati o anche della cura. Al motore non importava; forse sì.

Per evitare questi errori comuni o la restituzione involontaria dei dati, MySQL 5.7 attiva ONLY_FULL_GROUP_BY per impostazione predefinita.

Nel tuo caso, le righe sbagliate costituiscono i risultati presumibilmente per le colonne 2 e 3.

Vedere la pagina del manuale intitolata Gestione MySQL di GROUP BY .

Esempio 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);

Domanda:

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

Quanto sopra funziona alla grande su MySQL 5.6 e 5.7 indipendentemente dall'impostazione per ONLY_FULL_GROUP_BY

ora considera

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

Quanto sopra è spesso accettabile su MySQL 5.6 senza ONLY_FULL_GROUP_BY abilitato e fallisce su 5.7 con ONLY_FULL_GROUP_BY abilitato (errore 1055). L'output di cui sopra è fondamentalmente senza senso. Ma di seguito è spiegato un po ':

Sappiamo che Dirk, un Dirk, solo un Dirk, è l'unico a sopravvivere all'unione interiore. Ci sono 2 Dirk. Ma a causa del group by p.firstName , ci resta un solo Dirk. Abbiamo bisogno di un lastName . A causa della non conformità allo
lo standard SQL, MySQL può consentirlo con ONLY_FULL_GROUP_BY spento. Quindi sceglie qualsiasi vecchio cognome. Bene, il primo che trova, e quello è nella cache o quello nell'ordine fisico.

Ed è andato con Peters. La somma del conteggio dei frutti vale per tutti i Dirk.

Quindi, se codifichi in questo modo, il non conforme ONLY_FULL_GROUP_BY ti dà parole senza senso.

E come affermato, le navi MySQL 5.7 non lo consentivano per impostazione predefinita. Ma è modificabile alla vecchia maniera, se lo desideri.

Ti consigliamo vivamente di correggere le tue domande e di lasciare ONLY_FULL_GROUP_BY come abilitato.