Sto usando la seguente query per tempi di lavoro di gruppo e le spese per i clienti da tre tabelle, una per i clienti, uno per tempi di lavoro e uno per le spese:Utilizzando GROUP BY e ORDER BY in una query SQL INNER JOIN
SELECT a.*,
COALESCE(b.totalCount, 0) AS CountWork,
COALESCE(b.totalAmount, 0) AS WorkTotal,
COALESCE(c.totalCount, 0) AS CountExpense,
COALESCE(c.totalAmount, 0) AS ExpenseTotal
FROM clients A
LEFT JOIN
(
SELECT Client,
COUNT(*) totalCount,
SUM(Amount) totalAmount
FROM work_times
WHERE DATE BETWEEN '2013-01-01' AND '2013-02-01'
GROUP BY Client
) b ON a.Client = b.Client
LEFT JOIN
(
SELECT Client,
COUNT(*) totalCount,
SUM(Amount) totalAmount
FROM expenses
WHERE DATE BETWEEN '2013-01-01' AND '2013-02-01'
GROUP BY Client
) c ON a.Client = c.Client
WHERE b.Client IS NOT NULL OR
c.Client IS NOT NULL
È possibile visualizzare la query di lavoro su un violino here.
Sto tentando di modificare questa query in modo che sia presente una riga per ciascun client per ogni mese ordinato per mese e quindi client. Sto cercando di farlo con la seguente query modificata:
SELECT a.*,
COALESCE(b.totalCount, 0) AS CountWork,
COALESCE(b.totalAmount, 0) AS WorkTotal,
COALESCE(c.totalCount, 0) AS CountExpense,
COALESCE(c.totalAmount, 0) AS ExpenseTotal
FROM clients A
LEFT JOIN
(
SELECT Client,
COUNT(*) totalCount,
SUM(Amount) totalAmount,
SUBSTR(Date, 1, 7) as Month
FROM work_times
GROUP BY Month,Client
ORDER BY Month
) b ON a.Client = b.Client
LEFT JOIN
(
SELECT Client,
COUNT(*) totalCount,
SUM(Amount) totalAmount,
SUBSTR(Date, 1, 7) as Month
FROM expenses
GROUP BY Month,Client
ORDER BY Month,Client
) c ON a.Client = c.Client
WHERE b.Client IS NOT NULL OR
c.Client IS NOT NULL
Si può vedere la query modificata in azione here.
Non funziona comunque bene. Viene restituita una sola riga per il cliente B anche se a gennaio 2013 è previsto un orario di lavoro e una spesa a febbraio 2013 (quindi dovrebbero esserci 2 righe) e sembra che le righe siano ordinate dal cliente anziché dal mese. Qualcuno potrebbe suggerire come modificare la query per ottenere il risultato desiderato, che per l'esempio del secondo violino sarebbe:
╔════════╦═══════════╦═══════════╦══════════════╦══════════════╗
║ CLIENT ║ COUNTWORK ║ WORKTOTAL ║ COUNTEXPENSE ║ EXPENSETOTAL ║
╠════════╬═══════════╬═══════════╬══════════════╬══════════════╣
║ A ║ 1 ║ 10 ║ 1 ║ 10 ║
║ B ║ 1 ║ 20 ║ 0 ║ 0 ║
║ A ║ 1 ║ 15 ║ 0 ║ 0 ║
║ B ║ 0 ║ 0 ║ 1 ║ 10 ║
║ C ║ 1 ║ 10 ║ 0 ║ 0 ║
╚════════╩═══════════╩═══════════╩══════════════╩══════════════╝
Non è necessario il 'ORDINE BY' per i due sub-select. Mettilo per la risposta finale. –
Se la data è un tipo di dati datetime, perché/come si fa una sottostringa() su di esso? – wildplasser
Le tabelle contengono dati ridondanti, importo e data. È necessario normalizzare ulteriormente la struttura e sbarazzarsi della ridondanza. La query è troppo ambigua, desideri visualizzare dati specifici ma non ci sono criteri in nessuna selezione diversa da ** l'id del client non è nullo **. Se si desidera visualizzare i dati per un intervallo di date specificato, raggruppati per mese, quindi eseguire una ricerca per la data. Vorrei fare un passo indietro e guardare alla normalizzazione come il mio primo problema. –