2012-05-09 9 views
7

Può chiunque un aiuto che mi ottimizzare questa querystrano comportamento del Gruppo per in Query che ha bisogno di essere ottimizzato

SELECT 
    `debit_side`.`account_code` CODE, 
    GROUP_CONCAT(DISTINCT accounts.name) AS DebitAccount, 
    GROUP_CONCAT(debit_side.amount) AS DebitAmount, 
    GROUP_CONCAT(transaction_info.voucher_date) AS DebitVoucherDate, 
    (SELECT 
    GROUP_CONCAT(DISTINCT accounts.name) 
    FROM 
    (accounts) 
    LEFT JOIN debit_side 
     ON accounts.code = debit_side.account_code 
    LEFT JOIN credit_side 
     ON debit_side.transaction_id_dr = credit_side.transaction_id_cr 
    LEFT JOIN transaction_info 
     ON transaction_info.transaction_id = credit_side.transaction_id_cr 
    GROUP BY credit_side.account_code 
    HAVING credit_side.account_code = `Code`) AS CreditAccount, 
    (SELECT 
    GROUP_CONCAT(credit_side.amount) AS CreditAmount 
    FROM 
    (accounts) 
    LEFT JOIN debit_side 
     ON accounts.code = debit_side.account_code 
    LEFT JOIN credit_side 
     ON debit_side.transaction_id_dr = credit_side.transaction_id_cr 
    LEFT JOIN transaction_info 
     ON transaction_info.transaction_id = credit_side.transaction_id_cr 
    GROUP BY credit_side.account_code 
    HAVING credit_side.account_code = `Code`) AS CreditAmount, 
    (SELECT 
    GROUP_CONCAT(transaction_info.voucher_date) AS CreditVoucherDate 
    FROM 
    (accounts) 
    LEFT JOIN debit_side 
     ON accounts.code = debit_side.account_code 
    LEFT JOIN credit_side 
     ON debit_side.transaction_id_dr = credit_side.transaction_id_cr 
    LEFT JOIN transaction_info 
     ON transaction_info.transaction_id = credit_side.transaction_id_cr 
    GROUP BY credit_side.account_code 
    HAVING credit_side.account_code = `Code`) AS CreditVoucherDate 
FROM 
    (`accounts`) 
    LEFT JOIN `credit_side` 
    ON `accounts`.`code` = `credit_side`.`account_code` 
    LEFT JOIN `debit_side` 
    ON `debit_side`.`transaction_id_dr` = `credit_side`.`transaction_id_cr` 
    LEFT JOIN `transaction_info` 
    ON `transaction_info`.`transaction_id` = `credit_side`.`transaction_id_cr` 
GROUP BY `debit_side`.`account_code` 
HAVING `Code` IS NOT NULL 
ORDER BY `debit_side`.`account_code` ASC 

In realtà in questa query sto cercando di ottenere i dati per il lato di debito e sul lato del credito per tutti gli account. È necessario aver notato che le interrogazioni secondarie vengono ripetute ma selezionando colonne diverse. Questa query sta ottenendo risultati perfetti, ma voglio che sia ottimizzata. Ecco il link al mio schema

http://www.sqlfiddle.com/#!2/82274/6

precedenza avevo queste due domande, che ho cercato di coniugare

SELECT 
    debit_side.account_code DebitCode, 
    group_concat(distinct accounts.name) as DebitAccount, 
    group_concat(debit_side.amount) as DebitAmount, 
    group_concat(transaction_info.voucher_date) as DebitVoucherDate 
FROM (`accounts`) 
    LEFT JOIN `credit_side` 
    ON `accounts`.`code` = `credit_side`.`account_code` 
    LEFT JOIN `debit_side` 
    ON `debit_side`.`transaction_id_dr` = `credit_side`.`transaction_id_cr` 
    LEFT JOIN `transaction_info` 
    ON `transaction_info`.`transaction_id` = `credit_side`.`transaction_id_cr` 
GROUP BY `debit_side`.`account_code` 
ORDER BY `debit_side`.`account_code` ASC 

E

SELECT 
    credit_side.account_code CreditCode, 
    group_concat(distinct accounts.name) as CreditAccount, 
    group_concat(credit_side.amount) as CreditAmount, 
    group_concat(transaction_info.voucher_date) as CreditVoucherDate 
FROM (`accounts`) 
    LEFT JOIN `debit_side` 
    ON `accounts`.`code` = `debit_side`.`account_code` 
    LEFT JOIN `credit_side` 
    ON `debit_side`.`transaction_id_dr` = `credit_side`.`transaction_id_cr` 
    LEFT JOIN `transaction_info` 
    ON `transaction_info`.`transaction_id` = `credit_side`.`transaction_id_cr` 
GROUP BY `credit_side`.`account_code` 
ORDER BY `credit_side`.`account_code` ASC 

Anche io voglio rimuovere il record di nulla che è stato recuperato Nota: dovresti anche notare che nelle sottocommissioni sto usando condizioni leggermente diverse che risultano in base alle mie esigenze.

EDITS

ho covercome il problema per rimuovere il record nullo, ma l'ottimizzazione è lasciato ancora.

nuove modifiche

Ecco quello che ho provato con semi uniscono

SELECT 
    `lds`.`account_code` DebitCode, 
    group_concat(distinct la.name) as DebitAccount, 
    group_concat(lds.amount) as DebitAmount, 
    group_concat(lti.voucher_date) as DebitVoucherDate, 
    `rcs`.`account_code` CreditCode, 
    group_concat(distinct ra.name) as CreditAccount, 
    group_concat(rcs.amount) as CreditAmount, 
    group_concat(rti.voucher_date) as CreditVoucherDate 
FROM accounts as la 
    LEFT join accounts as ra 
    ON ra.`code` = la.`code` 
    LEFT JOIN `credit_side` as lcs 
    ON `la`.`code` = `lcs`.`account_code` 
    LEFT JOIN `debit_side` as lds 
    ON `lds`.`transaction_id_dr` = `lcs`.`transaction_id_cr` 
    LEFT JOIN `transaction_info` as lti 
    ON `lti`.`transaction_id` = `lcs`.`transaction_id_cr` 
    LEFT JOIN `debit_side` as rds 
    ON `ra`.`code` = `rds`.`account_code` 
    LEFT JOIN `credit_side` rcs 
    ON `rds`.`transaction_id_dr` = `rcs`.`transaction_id_cr` 
    LEFT JOIN `transaction_info` as rti 
    ON `rti`.`transaction_id` = `rcs`.`transaction_id_cr` 
GROUP BY `CreditCode` 
HAVING `CreditCode` IS NOT NULL 
ORDER BY `CreditCode` ASC 

La cosa strana è che se cambio di gruppo avendo e l'ordine da parte con DebitCode esso portare record perfetto per il lato di debito e se Io cambio questo con CreditCode se porta record perfetti per il lato del credito. C'è un modo per superare questo problema o qualsiasi alternativa.

+0

Potresti postare l'output 'EXPLAIN' per quella query? – eggyal

+0

@eggyal - solo per quello che sai, l'output EXPLAIN è disponibile all'interno del link sqlfiddle, se espandi "Visualizza piano di esecuzione" –

+0

@JakeFeasel: Grazie! In realtà, sapevo che sqlfiddle ha mostrato il piano di esecuzione ... Non ho individuato il collegamento sqlfiddle quando ho scansionato questa domanda (penso di aver visto "ecco il mio schema" e ho trascurato dove si collegava). – eggyal

risposta

3

Ho esaminato il tuo schema e SQL per un po 'e non capisco la tua logica. Le cose come le vedo:

  • si ha una serie di transazioni (9 per la precisione);
  • per ogni transazione si dispone di dettagli sulle parti di debito e di credito;
  • utilizzando lo account_code su ciascun lato, è possibile ottenere informazioni sugli account.

Quindi, vorrei andare in questo modo per i dispositivi di avviamento e creato uno VIEW, che fornirebbe tutte le informazioni necessarie per le vostre transazioni. Ho usato INNER unisce qui, come credo ogni transazione deve avere entrambi, di debito e credito lati, e ogni lato, a sua volta, dovrebbe avere un conto:

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; 

Ora, guardando le vostre domande, è sembra che tu stia cercando di ottenere un elenco di tutte le operazioni sul lato opposto per ogni codice account.Non sono sicuro di quale sia lo scopo di questo, ma farei quanto segue:

  • selezionato un elenco di codici account univoci;
  • creato un elenco aggregato di operazioni lato debito per ciascun codice account, dove tale codice era sul lato del credito;
  • ha creato lo stesso elenco aggregato per operazioni lato credito, laddove tale conto si trovava sul lato del debito;
  • e inserire ciascun codice account nel mezzo.

Quindi qualcosa di simile potrebbe fare il lavoro:

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; 

Nella parte interna sto simulando FULL OUTER uniscono unendo 2 altri join, LEFT e RIGHT quelli. E la parte esterna esegue tutti i raggruppamenti. Take a look at the result.

Si noti che se si desidera aggiungere/rimuovere colonne dal risultato, è necessario modificare entrambe le query interne ed esterne.

Spero che questo sia quello che stavate cercando.

+0

Beh, sembra che tu abbia perfettamente capito la domanda perché è esattamente quello che stavo cercando. Grazie per il vostro aiuto con questa query ho imparato alcune tecniche più importanti con mysql. Grazie molto –

Problemi correlati