Placez une sous-requête qui renvoie plusieurs colonnes dans le FROM
liste et sélectionnez-la.
Une sous-requête corrélée serait une mauvaise idée pour commencer. Cependant, votre requête n'est même pas corrélée, mais non liée (pas de lien vers la requête externe) et semble renvoyer plusieurs lignes. Cela conduit à une jointure croisée (peut-être très coûteuse et absurde) produisant un produit cartésien, probablement pas votre intention (secrète).
Apparemment, vous voulez vraiment :
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);
Les deux LEFT JOIN
sont également inutiles. Celui en sale
est forcé à un INNER JOIN
par la condition WHERE. Celui sur mat semble inutile, puisque vous GROUP BY mat.mat
- sauf si vous êtes intéressé par mat IS NULL
? (J'en doute.)
Le cas peut probablement être encore simplifié en :
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;
Le WHERE
condition peut probablement être simplifiée davantage, en fonction de vos types de données secrètes et de vos index. Une cargaison d'informations sur précisément ce cas dans cette réponse connexe sur dba.SE
.