Viděl jsem následující dotaz MySQL, který používá DISTINCT i GROUP BY společně:
SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%";
Zde je scénář k zadání dotazu: Každý uživatel má jedinečné ID, user_id
, a může vytvořit více příspěvků, které jsou identifikovány jedinečným ID, post_id
. Každý příspěvek by obsahoval nějaký text.
Považoval jsem to za matoucí (po příchodu z Oracle DB) a měl jsem následující otázky:
- Jaký je význam použití
GROUP BY
bez provedení agregace? - Jaký je význam přepínání pořadí sloupců v
SELECT
vs vGROUP BY
? - Co znamená vynechání třetího sloupce z
GROUP BY
? - Proč je
DISTINCT
použitý spolu sGROUP BY
? Spustí se odlišná operace po provedení všech seskupení u konečného výsledku nebo dříve?
Komentáře
Odpověď
reklama 1) Staré databáze mysql a když zakážete ONLY_FULL_GROUP_BY , můžete provést tento dotaz a pokud je post_content stejný, všimnete si, že mysql poskytuje náhodnou, nikoli deterministickou hodnotu zpět .
reklama 2) žádná, co vůbec
reklama 3) líné programování a při povolení ONLY_FULL_GROUP_BY dojde k chybě a>
reklama 4) Ne, zobrazil by všechny post_content, které jsou připojeny k user_id, post_id podobné addind post_content do skupiny od
Stejně jako již řekl Strawberry, tento dotaz není dávat smysl
Odpovědět
Šílená schopnost povolit částečné seskupování ve starších verzích MyS QL, musí být jedním z nejlepších uchazečů o většinu způsobených zmatků v IT průmyslu.
Vzhledem k tabulce:
CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2);
Prohlášení
SELECT x, y FROM t GROUP BY x
může znamenat (1,1) nebo (1,2) a MySQL by náhodně jeden z nich vrátil. V tomto případě na DISTINCT nezáleží, výsledek je stále deterministický.
SQL92 vyžaduje, aby všechny sloupce v klauzuli select (kromě agregovaných sloupců a konstant) byly součástí klauzule GROUP BY.
SQL99 toto omezení trochu uvolnil a umožnil nám vynechat sloupce ze skupiny GROUP BY, které jsou funkčně závislé na zbývajících sloupcích. Tj.
CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x
bude platit, protože y je f.d. of x
Překvapivě (pro mě) je pozdější verze MySQL nejlepší ve své třídě, pokud jde o implementaci verze SQL99. V poslední době jsem to nekontroloval, ale když jsem to udělal, MySQL zvládl docela komplikované scénáře dobře, zatímco PostgreSQL zpracoval pouze triviální.
Odpovědi na vaše dotazy
1)
SELECT x, y FROM t GROUP BY x, y
znamená, že kombinace x, y je skupina. Ve všech možných situacích si myslím, že je to stejné jako:
SELECT DISTINCT x, y FROM t
Vzhledem k tomu, že jsou logicky vyhodnocovány v různých časech, může dojít k nějakému rohovému případu, kdy by se skutečně lišily (na jednu však nemyslím)
2) Žádné , v tomto ohledu se jedná o sadu sloupců, takže neexistuje žádné pořadí
3) Viz výše.
4) Logické pořadí vyhodnocení dotazu SQL je:
FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST
takže skupina GROUP BY má být hodnocena před DISTINCT. Nenapadá mě situace, kde by to záleželo.
Ve vašem dotazu Mám podezření, že někdo dostal matoucí výsledky a pokusil se získat jiný výsledek pomocí DISTINCT. Pravděpodobně měli štěstí (nebo smůlu) získat výsledek očekáváno, takže DISTINCT zůstal. Chyba tu stále je
GROUP BY
vůbec nezáleží (až na to, že ve starých verzích to implikovalo totéžORDER BY
.SELECT
na pořadí záleží pouze v uspořádání sloupců ve výstupu.