sql >> Database >  >> RDS >> Mysql

Is er een manier om een ​​WHERE-clausule te tonen voor slechts één veld in MySQL?

Vóór MySQL 5.7 was de standaardinstelling om niet-VOLLEDIGE group by toe te staan . Wat betekent dat je een groep kunt hebben op (die gebruikmaakt van geaggregeerde functies zoals sum en max en count en group_concat ) met andere niet-geaggregeerde kolommen (laten we ze NON AGGS noemen) ) vind je eerste 3 leuk niet allemaal onderdeel van je group by clausule. Het stond het toe, maar de resultaten zouden normaal gesproken als volgt uitpakken:

  • Het werkte geweldig omdat u uw gegevens goed kent en probeert een duidelijk

  • Het werkte verschrikkelijk omdat het een snafu was

Vóór 5.7, ONLY_FULL_GROUP_BY bestond maar was standaard UITGESCHAKELD.

Dus in MySQL 5.7 komt de ONLY_FULL_GROUP_BY standaard AAN. Als zodanig als u een groep probeert op, maar met niet alle de NON AGGS in de group by clausule, krijgt u een Error.

Beschouw het volgende probleem in 5.6 hieronder:

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

Wat hierboven gebeurt, is niet alle NON AGGS zijn in de group by . Het retourneert de max (leeftijd) door col1. Maar sinds col2 zat niet in de group by , het gebruikte de Cluster Index of Physical Ordering en bracht het, per ongeluk misschien (een snafu, een fout), de verkeerde waarde voor col2. Afhankelijk van uw bedoelingen of wetende uw gegevens of zelfs zorgzaam. De motor maakte het niet uit; misschien wel.

Om deze veelvoorkomende fouten of onbedoelde gegevensteruggave te voorkomen, schakelt MySQL 5.7 ONLY_FULL_GROUP_BY in standaard.

In uw geval vormen de verkeerde rijen uw resultaten vermoedelijk voor de kolommen 2 en 3.

Zie de pagina met de handleiding met de titel MySQL-afhandeling van GROUP BY .

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

Vraag:

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

Het bovenstaande werkt prima op MySQL 5.6 en 5.7, ongeacht de instelling voor ONLY_FULL_GROUP_BY

overweeg nu

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

Het bovenstaande is vaak acceptabel op MySQL 5.6 zonder ONLY_FULL_GROUP_BY ingeschakeld en mislukt op 5.7 met ONLY_FULL_GROUP_BY ingeschakeld (fout 1055). De bovenstaande uitvoer is eigenlijk wartaal. Maar hieronder wordt het enigszins uitgelegd:

We weten dat Dirk, een Dirk, gewoon ene Dirk, de enige is die de binnenband overleeft. Er zijn 2 Dirks. Maar vanwege de group by p.firstName , we hebben nog maar één Dirk over. We hebben een lastName nodig . Vanwege de niet-conformiteit met
de SQL-standaard, kan MySQL dit toestaan ​​met ONLY_FULL_GROUP_BY uitgeschakeld. Dus het kiest gewoon een oude achternaam. Welnu, de eerste die het vindt, en dat is ofwel in de cache of degene in de fysieke bestelling.

En het ging met Peters. De fruittelsom is voor alle Dirks.

Dus als je op deze manier codeert, wordt de niet-conforme niet-ONLY_FULL_GROUP_BY geeft je wartaal.

En zoals gezegd, MySQL 5.7-schepen stonden dit standaard niet toe. Maar het is aanpasbaar naar de oude manier als je ervoor kiest.

Het wordt ten zeerste aanbevolen dat u uw vragen oplost en ONLY_FULL_GROUP_BY . verlaat zoals ingeschakeld.



  1. Definieer de stappen voor de SQL Server-cursor - SQL Server / TSQL-zelfstudie

  2. ResultSet#getDate() semantiek

  3. Hoe SQLite op macOS te installeren

  4. SCD-type 1