Inserisci una sottoquery che restituisca più colonne nel FROM
elenco e selezionarlo.
Una sottoquery correlata sarebbe una cattiva idea per cominciare. Tuttavia, la tua query non è nemmeno correlata, ma non correlata (nessun collegamento alla query esterna) e sembra restituire più righe. Questo porta a (forse molto costoso e senza senso) cross join che producono un prodotto cartesiano, probabilmente non la tua intenzione (segreta).
Sembra che tu voglia davvero:
SELECT m1.mat AS mat1, m1.sumtotal AS sumtotal1
,m2.mat AS mat2, m2.sumtotal AS sumtotal2
FROM (
SELECT mat.mat, sum(stx.total) AS sumtotal
FROM stx
LEFT JOIN mat ON mat.matid = stx.matid
LEFT JOIN sale ON stx.saleid = sale.id
WHERE stx.date BETWEEN '2013-05-01' AND '2013-08-31'
AND sale.userid LIKE 'A%'
GROUP BY mat.mat
) m1
JOIN (
SELECT mat.mat, sum(stx.total) AS sumtotal
FROM stx
LEFT JOIN mat ON mat.matid = stx.matid
LEFT JOIN sale ON sale.id = stx.saleid
WHERE stx.date BETWEEN '2013-05-01' AND '2013-08-31'
AND sale.userid LIKE 'b%'
GROUP BY mat.mat
) m2 USING (mat);
Entrambi LEFT JOIN
sono anche inutili. Quello in sale
è forzato a un INNER JOIN
dalla condizione WHERE. Quello sul tappetino sembra inutile, dal momento che GROUP BY mat.mat
- salvo se sei interessato a mat IS NULL
? (Ne dubito.)
Il caso può probabilmente essere ulteriormente semplificato in:
SELECT m.mat
,sum(CASE WHEN s.userid LIKE 'A%' THEN x.total END) AS total_a
,sum(CASE WHEN s.userid LIKE 'B%' THEN x.total END) AS total_b
FROM sale s
JOIN stx x ON x.saleid = s.id
JOIN mat m ON m.matid = x.matid
WHERE (s.userid LIKE 'A%' OR s.userid LIKE 'B%')
AND x.date BETWEEN '2013-05-01' AND '2013-08-31'
GROUP BY 1;
Il WHERE
condizione può probabilmente essere ulteriormente semplificata, a seconda dei tipi e degli indici di dati segreti. Un carico di informazioni proprio su quel caso in questa risposta correlata su dba.SE
.