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

Podivné chování skupiny v dotazu, které je třeba optimalizovat

Chvíli jsem se díval na vaše schéma a SQL a úplně nerozumím vaší logice. Věci, jak je vidím já:

  • máte sadu transakcí (přesně 9);
  • pro každou transakci máte podrobnosti o debetní a kreditní straně;
  • pomocí account_code na každé straně můžete získat informace o účtech.

Pro začátek bych tedy šel touto cestou a vytvořil VIEW , který by vám poskytl všechny potřebné informace o vašich transakcích. Použil jsem INNER se připojí zde, protože věřím, že každá transakce musí mít obě, debetní i kreditní stranu, a každá strana by měla mít účet:

CREATE VIEW all_transactions AS
SELECT ti.transaction_id tid, ti.voucher_no tvno, ti.voucher_date tvdt,
       ds.account_code dacc, ds.amount damt, da.name daname, da.type dat,
       cs.account_code cacc, cs.amount camt, ca.name caname, ca.type cat
  FROM transaction_info ti
  JOIN debit_side ds ON ds.transaction_id_dr = ti.transaction_id
  JOIN credit_side cs ON cs.transaction_id_cr = ti.transaction_id
  JOIN accounts da ON da.code = ds.account_code
  JOIN accounts ca ON ca.code = cs.account_code;

Nyní se při pohledu na vaše dotazy zdá, že se snažíte získat seznam všech protistranných operací pro každý kód účtu. Nejsem si jistý, jaký to má účel, ale udělal bych následující:

  • vybrali seznam jedinečných kódů účtů;
  • vytvořili agregovaný seznam operací na straně debetu pro každý kód účtu, pokud byl tento kód na straně kreditu;
  • vytvořil stejný agregovaný seznam pro operace na straně kreditu, kde byl takový účet na straně debetu;
  • a každý kód účtu vložte doprostřed.

Takže něco takového by mohlo fungovat:

SELECT group_concat(dacc) "D-Accounts",
       group_concat(damt) "D-Amounts",
       group_concat(daname) "D-Names",
       group_concat(dvdt) "D-Dates",
       code, name,
       group_concat(cacc) "C-Accounts",
       group_concat(camt) "C-Amounts",
       group_concat(caname) "C-Names",
       group_concat(cvdt) "C-Dates"
  FROM (
    SELECT atl.dacc, atl.damt, atl.daname, atl.tvdt dvdt,
           a.code, a.name, NULL cacc, NULL camt, NULL caname, NULL cvdt
      FROM accounts a
      LEFT JOIN all_transactions atl ON atl.cacc = a.code
    UNION ALL
    SELECT NULL, NULL, NULL, NULL, a.code, a.name,
           atr.cacc, atr.camt, atr.caname, atr.tvdt cvdt
      FROM accounts a
      RIGHT JOIN all_transactions atr ON atr.dacc = a.code
  ) full_join
 GROUP BY code, name
 ORDER BY code;

Ve vnitřní části simuluji FULL OUTER připojte se spojením 2 dalších spojení, LEFT a RIGHT jedničky. A vnější část provádí všechna seskupení. Podívejte se na výsledek .

Všimněte si, že pokud chcete přidat/odebrat sloupce z výsledku, měli byste upravit vnitřní i vnější dotazy.

Doufám, že to je to, co jste hledali.




  1. SQL přebírá pouze číselné hodnoty z varcharu

  2. Připnutí tabulky do mezipaměti Flash

  3. Dotaz nevrací výsledky podle očekávání

  4. Chyba .NET a MySQL - Volání SSPI selhalo ... přijatá zpráva byla neočekávaná nebo špatně naformátovaná A vyrovnávací paměti dodané funkci byly příliš malé