Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Seltsames Verhalten von Group by in Query, das optimiert werden muss

Ich habe mich eine Weile mit Ihrem Schema und SQL beschäftigt und verstehe Ihre Logik nicht ganz. Dinge, wie ich sie sehe:

  • Sie haben eine Reihe von Transaktionen (9 um genau zu sein);
  • für jede Transaktion haben Sie Angaben zur Soll- und Habenseite;
  • unter Verwendung des account_code Auf jeder Seite können Sie Informationen über Konten erhalten.

Also würde ich für den Anfang diesen Weg gehen und eine VIEW erstellen , die Ihnen alle notwendigen Informationen zu Ihren Transaktionen liefern würde. Ich habe INNER verwendet reiht sich hier ein, wie ich glaube, jede Transaktion muss haben sowohl eine Soll- als auch eine Habenseite, und jede Seite sollte wiederum ein Konto haben:

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;

Wenn Sie sich jetzt Ihre Abfragen ansehen, scheinen Sie zu versuchen, eine Liste aller Gegenoperationen für jeden Kontocode zu erhalten. Ich bin mir nicht sicher, was der Zweck davon ist, aber ich würde Folgendes tun:

  • eine Liste eindeutiger Kontocodes ausgewählt;
  • erstellte eine aggregierte Liste der debitorischen Vorgänge für jeden Kontocode, wenn sich dieser Code auf der Habenseite befand;
  • erstellte dieselbe aggregierte Liste für kreditseitige Transaktionen, bei denen sich ein solches Konto auf der Sollseite befand;
  • und setzen Sie jeden Kontocode in die Mitte.

So etwas wie das könnte die Arbeit erledigen:

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;

Im inneren Teil simuliere ich FULL OUTER Join durch Vereinigung von 2 anderen Joins, LEFT und RIGHT Einsen. Und der äußere Teil führt alle Gruppierungen durch. Sehen Sie sich das Ergebnis an .

Beachten Sie, dass Sie, wenn Sie Spalten zum Ergebnis hinzufügen/entfernen möchten, sowohl die inneren als auch die äußeren Abfragen ändern sollten.

Ich hoffe, das ist, wonach Sie gesucht haben.