Plaats een subquery die meerdere kolommen retourneert in de FROM
lijst en maak er een keuze uit.
Een gecorreleerde subquery zou om te beginnen een slecht idee zijn. Uw zoekopdracht is echter niet eens gecorreleerd, maar niet-gerelateerd (geen link naar buitenste query) en lijkt meerdere rijen te retourneren. Dit leidt tot (mogelijk erg dure en onzinnige) cross join die een cartesiaans product produceert, waarschijnlijk niet je (geheime) bedoeling.
Het lijkt erop dat je echt wilt:
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);
Beide LEFT JOIN
zijn ook zinloos. Die in sale
wordt gedwongen tot een INNER JOIN
door de WHERE-voorwaarde. Die op mat lijkt zinloos, aangezien je GROUP BY mat.mat
- behalve als u geïnteresseerd bent in mat IS NULL
? (Ik betwijfel het.)
De zaak kan waarschijnlijk verder worden vereenvoudigd tot:
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;
De WHERE
voorwaarde kan waarschijnlijk verder worden vereenvoudigd, afhankelijk van uw geheime gegevenstypes en indices. Een lading informatie over precies dat geval in dit gerelateerde antwoord op dba.SE
.