Place a subquery that returns multiple columns in the FROM list and select from it.
A correlated subquery would be a bad idea to start with. However, your query is not even correlated, but unrelated (without reference to an external query) and seems to return multiple rows. This leads to a (possibly very expensive and meaningless) cross-coupling that creates Cartesian products, perhaps not your (secret) intention.
It looks like you really want:
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);
Both LEFT JOIN also meaningless. The one on sale forced to INNER JOIN the WHERE clause. What on the mat seems pointless since you are GROUP BY mat.mat - unless you are interested in mat IS NULL ? (I doubt).
This could probably be simplified:
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;
Perhaps the WHERE may be simplified, depending on your secret data types and indexes. Boat information about this case in this related answer to dba.SE.
source share