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

Vícenásobné poddotazy MySQL vs. celé dotazy

Protože tyto tři agregáty pocházejí ze stejné tabulky se stejným WHERE podmínky, nepotřebujete podvýběry. Všechny tři agregáty fungují na stejném seskupení řádků (bez GROUP BY zadané, takže jeden řádek pro celou tabulku), takže mohou všechny existovat v SELECT vypsat přímo.

SELECT
  SUM(number) AS number_sum,
  MAX(number) AS number_max,
  MIN(number) AS number_min
FROM `table`

Pokud je třeba, aby některý z agregátů vycházel z různých podmínek, filtrovali byste pomocí WHERE klauzuli, pak budete muset buď použít podvýběr pro odlišnou podmínku, nebo provést kartézské spojení. Tento dílčí výběr a následující LEFT JOIN metoda by měla být z hlediska výkonu ekvivalentní pro agregáty vracející pouze jeden řádek:

SELECT
  /* Unique filtering condition - must be done in a subselect */
  (SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum,
  MAX(number) AS number_max,
  MIN(number) AS number_min
FROM `table`

Nebo ekvivalentně k výše uvedenému dotazu můžete LEFT JOIN proti poddotazu bez ON doložka . To by mělo být provedeno pouze v situacích, kdy víte, že poddotaz vrátí pouze jeden řádek. V opačném případě skončíte s kartézským součinem – tolik řádků, kolik vrátí jedna strana spojení násobeno počet řádků vrácených druhou stranou.

To je užitečné, pokud potřebujete vrátit několik sloupců s jednou sadou WHERE podmínky klauzule a několik sloupců s jinou sadou WHERE podmínky, ale pouze jednu řádek z každé strany JOIN . V tomto případě by mělo být rychlejší JOIN než udělat dva podvýběry se stejným WHERE doložka.

To by mělo být rychlejší....

SELECT
  /* this one has two aggregates sharing a WHERE condition */
  subq.number_sum_filtered,
  subq.number_max_filtered,
  /* ...and two aggregates on the main table with no WHERE clause filtering */
  MAX(`table`.number) AS number_max,
  MIN(`table`.number) AS number_min
FROM
  `table`
  LEFT JOIN (
    SELECT 
       SUM(number) AS number_sum_filtered,
       MAX(number) AS number_max_filtered
    FROM `table`
    WHERE `somecolumn = `somevalue`
  ) subq /* No ON clause here since there's no common column to join on... */

Než toto...

SELECT
  /* Two different subselects each over the same filtered set */
  (SELECT SUM(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_sum_filtered,
  (SELECT MAX(number) FROM `table` WHERE `somecolumn` = `somevalue`) AS number_max_filtered,
  MAX(`table`.number) AS number_max,
  MIN(`table`.number) AS number_min
FROM
  `table`



  1. Jak hledat více klíčových slov v sql

  2. CHAR() nebo VARCHAR() jako primární klíč v tabulce ISAM MySQL?

  3. Štípací struny:Následné

  4. Převeďte soubor z Cp1252 na utf -8 java