sql >> Base de Datos >  >> RDS >> Mysql

Comportamiento extraño de Agrupar por en consulta que debe optimizarse

He estado investigando su esquema y SQL por un tiempo y no entiendo muy bien su lógica. Las cosas como las veo:

  • tiene un conjunto de transacciones (9 para ser precisos);
  • para cada transacción, tiene detalles en los lados de débito y crédito;
  • utilizando el account_code en cada lado, puede obtener información sobre las cuentas.

Entonces, para empezar, iría por este camino y crearía un VIEW , que le brindaría toda la información necesaria sobre sus transacciones. He usado INNER se une aquí, ya que creo que cada transacción debe tener ambos lados, débito y crédito, y cada lado, a su vez, debe tener una cuenta:

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;

Ahora, al observar sus consultas, parece que está tratando de obtener una lista de todas las operaciones del lado contrario para cada código de cuenta. No estoy seguro de cuál es el propósito de esto, pero haría lo siguiente:

  • seleccionó una lista de códigos de cuenta únicos;
  • creó una lista agregada de operaciones del lado del débito para cada código de cuenta, donde dicho código estaba del lado del crédito;
  • creó la misma lista agregada para operaciones del lado del crédito, donde dicha cuenta estaba del lado del débito;
  • y coloque cada código de cuenta en el medio.

Así que algo como esto podría hacer el trabajo:

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;

En la parte interna estoy simulando FULL OUTER unirse uniendo otras 2 uniones, LEFT y RIGHT unos. Y la parte exterior realiza todas las agrupaciones. Mira el resultado .

Tenga en cuenta que si desea agregar/eliminar columnas del resultado, debe modificar las consultas tanto internas como externas.

Espero que esto sea lo que estabas buscando.