sql >> Databáze >  >> RDS >> Mysql

Existuje způsob, jak zobrazit klauzuli WHERE pouze pro jedno pole v MySQL?

Před MySQL 5.7 bylo výchozí nastavení povolit nePLNÉ group by . Což znamená, že můžete mít skupinu podle (která používá agregační funkce jako sum a max a count a group_concat ) s dalšími neagregovanými sloupci (říkejme jim NON AGGS ) jako vaše první 3 zobrazené ne všechny součástí vaší group by doložka. Umožnilo to, ale výsledky by obvykle dopadly takto:

  • Fungovalo to skvěle, protože svá data dobře znáte a snažíte se dosáhnout zřetelného

  • Dopadlo to strašně, protože to byl snafu

Před verzí 5.7 ONLY_FULL_GROUP_BY existoval, ale ve výchozím nastavení byl vypnutý.

V MySQL 5.7 tedy přichází ONLY_FULL_GROUP_BY výchozí ON. Pokud se pokusíte seskupit podle, ale s ne všemi NON AGGS v group by klauzule, dostanete chybu.

Zvažte následující problém v 5.6 níže:

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 se děje výše, není všechno NON AGGS jsou v group by . Vrací max(věk) pomocí col1. Ale protože col2 nebyl ve group by , použil Cluster Index nebo Physical Ordering a přinesl mu, možná nedopatřením (snafu, chyba), špatnou hodnotu pro col2. V závislosti na vašich záměrech nebo znalosti vašich dat nebo dokonce péče. Motoru to bylo jedno; možná ano.

Aby se předešlo těmto běžným chybám nebo neúmyslnému návratu dat, MySQL 5.7 zapne ONLY_FULL_GROUP_BY ve výchozím nastavení.

Ve vašem případě tvoří vaše výsledky pravděpodobně pro sloupce 2 a 3 nesprávné řádky.

Viz manuálovou stránku s názvem MySQL Handling of GROUP BY .

Příklad 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);

Dotaz:

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

Výše uvedené funguje skvěle na MySQL 5.6 a 5.7 bez ohledu na nastavení pro ONLY_FULL_GROUP_BY

nyní zvažte

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

Výše uvedené je často přijatelné na MySQL 5.6 bez ONLY_FULL_GROUP_BY povoleno a selže ve verzi 5.7 s ONLY_FULL_GROUP_BY povoleno (chyba 1055). Výše uvedený výstup je v podstatě blábol. Ale níže je to trochu vysvětleno:

Víme, že Dirk, Dirk, jen jeden Dirk, je jediný, kdo přežije vnitřní spojení. Jsou tam 2 Dirkové. Ale kvůli group by p.firstName , zbyl nám jen jeden Dirk. Potřebujeme lastName . Vzhledem k neshodě s
standardem SQL to může MySQL povolit s ONLY_FULL_GROUP_BY vypnutý. Takže to prostě vybere jakékoli staré příjmení. No, první, kterou najde, a to je buď v mezipaměti, nebo ve fyzickém uspořádání.

A šlo to s Petersem. Součet počtu ovoce je pro všechny Dirky.

Pokud tedy kódujete takto, nevyhovující nevyhovující ONLY_FULL_GROUP_BY dává vám blábol.

A jak bylo uvedeno, MySQL 5.7 se standardně dodává tak, že to neumožňuje. Pokud si to však přejete, lze jej upravit na starý způsob.

Důrazně doporučujeme, abyste své dotazy opravili a opustili ONLY_FULL_GROUP_BY jako povoleno.



  1. Advanced SQL:Variace a různé případy použití T-SQL Insert Statement

  2. Deklarace struktury n-tice záznamu v PL/pgSQL

  3. Průvodce návrhem databáze pro systém sociálních sítí v MySQL

  4. Funkce Snapshot Controlfile pomocí RMAN a ORA-00245