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

Chyba související s only_full_group_by při provádění dotazu v MySql

Jen bych přidal group_id do GROUP BY .

Když SELECT sloupec, který není součástí GROUP BY ve skupinách může být více hodnot pro tento sloupec, ale ve výsledcích bude místo pouze pro jednu hodnotu. Databáze tedy obvykle je třeba přesně říci, jak z těchto více hodnot vytvořit jednu hodnotu. Obvykle se to provádí pomocí agregační funkce, jako je COUNT() , SUM() , MAX() atd... říkám obvykle protože většina ostatních populárních databázových systémů na tom trvá. V MySQL před verzí 5.7 však bylo výchozí chování shovívavější, protože si nebude stěžovat a poté svévolně zvolí libovolnou hodnotu ! Má také ANY_VALUE() funkce, která by mohla být použita jako další řešení této otázky, pokud byste skutečně potřebovali stejné chování jako dříve. Tato flexibilita něco stojí, protože je nedeterministická, takže bych ji nedoporučoval, pokud nemáte velmi dobrý důvod ji potřebovat. MySQL nyní zapíná only_full_group_by z dobrých důvodů je výchozí nastavení, takže je nejlepší si na to zvyknout a zajistit, aby vaše dotazy odpovídaly.

Tak proč moje jednoduchá odpověď výše? Udělal jsem několik předpokladů:

1) group_id je jedinečný. Zdá se rozumné, je to koneckonců 'ID'.

2) group_name je také unikátní. To nemusí být tak rozumný předpoklad. Pokud tomu tak není a máte nějaké duplicitní group_names a poté následujte moji radu a přidejte group_id do GROUP BY , možná zjistíte, že nyní získáte více výsledků než dříve, protože skupiny se stejným názvem budou mít nyní ve výsledcích samostatné řádky. Pro mě by to bylo lepší, než mít tyto duplicitní skupiny skryté, protože databáze si tiše vybrala hodnotu svévolně!

Je také dobrým zvykem kvalifikovat všechny sloupce jejich názvem tabulky nebo aliasem, pokud se jedná o více než jednu tabulku...

SELECT 
  g.group_id AS 'value', 
  g.group_name AS 'text' 
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id 
WHERE g.active = 1 
  AND g.department_id = 1 
  AND g.manage_work_orders = 1 
  AND g.group_name != 'root' 
  AND g.group_name != 'superuser' 
GROUP BY 
  g.group_name, 
  g.group_id 
HAVING COUNT(d.user_id) > 0 
ORDER BY g.group_name


  1. Budování a údržba HR databáze

  2. Převeďte nový řádek na XML v rámci Oracle Trigger

  3. Jak flexibilní/omezující jsou typy sloupců SQLite?

  4. Jak omezit řádky v sadě výsledků MySQL