Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Dziwne zachowanie grupy w zapytaniu, które należy zoptymalizować

Zaglądałem do twojego schematu i SQL przez jakiś czas i nie do końca rozumiem twoją logikę. Rzeczy tak, jak je widzę:

  • masz zestaw transakcji (dokładnie 9);
  • dla każdej transakcji masz szczegóły po stronie debetowej i kredytowej;
  • za pomocą account_code z każdej strony możesz uzyskać informacje o kontach.

Więc na początek poszedłbym w ten sposób i stworzyłem VIEW , które dostarczyłyby Ci wszystkich niezbędnych informacji o Twoich transakcjach. Użyłem INNER dołącza tutaj, ponieważ uważam, że każda transakcja musi mieć obie strony, debetową i kredytową, a każda strona z kolei powinna mieć konto:

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;

Teraz, patrząc na twoje zapytania, wygląda na to, że próbujesz uzyskać listę wszystkich operacji przeciwnych dla każdego kodu konta. Nie jestem pewien, jaki jest tego cel, ale zrobiłbym tak:

  • wybrałeś listę unikalnych kodów kont;
  • utworzył zagregowaną listę operacji po stronie debetowej dla każdego kodu konta, gdzie taki kod znajdował się po stronie kredytowej;
  • utworzył tę samą zagregowaną listę dla operacji po stronie kredytowej, gdzie takie konto było po stronie debetowej;
  • i umieść każdy kod konta na środku.

Więc coś takiego może załatwić sprawę:

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;

W części wewnętrznej symuluję FULL OUTER dołącz, łącząc 2 inne połączenia, LEFT i RIGHT te. A zewnętrzna część wykonuje wszystkie zgrupowania. Spójrz na wynik .

Pamiętaj, że jeśli chcesz dodać/usunąć kolumny z wyniku, powinieneś zmodyfikować zarówno zapytania wewnętrzne, jak i zewnętrzne.

Mam nadzieję, że tego właśnie szukałeś.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL:Podsumuj wszystkie liczby wierszy w tabeli w jednym zapytaniu

  2. Kolekcja Mapped Statements nie zawiera wartości dla mybatis mapper

  3. Jak uniknąć fragmentacji podczas używania klucza podstawowego NHibernate guid.comb w MySQL?

  4. last_insert_id() a SELECT Max (ID)

  5. Dlaczego wyszukiwanie w Gmailu jest tak szybkie?