Letakkan subquery yang mengembalikan beberapa kolom di FROM
daftar dan pilih darinya.
Subquery yang berkorelasi akan menjadi ide yang buruk untuk memulai. Namun, kueri Anda bahkan tidak berkorelasi, tetapi tidak terkait (tidak ada tautan ke kueri luar) dan tampaknya mengembalikan beberapa baris. Hal ini menyebabkan (mungkin sangat mahal dan tidak masuk akal) bergabung silang menghasilkan produk kartesius, mungkin bukan niat (rahasia) Anda.
Sepertinya Anda sangat menginginkan:
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);
Keduanya LEFT JOIN
juga tidak ada gunanya. Yang sedang sale
dipaksa untuk INNER JOIN
dengan kondisi WHERE. Yang di matras sepertinya tidak ada gunanya, karena Anda GROUP BY mat.mat
- kecuali jika Anda tertarik dengan mat IS NULL
? (Saya meragukannya.)
Kasus ini mungkin dapat disederhanakan lebih lanjut menjadi:
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;
WHERE
kondisi mungkin dapat disederhanakan lebih lanjut, tergantung pada tipe dan indeks data rahasia Anda. Banyak informasi tentang kasus itu di jawaban terkait ini di dba.SE
.