Đặt một truy vấn con trả về nhiều cột trong FROM
liệt kê và chọn từ nó.
Một truy vấn con tương quan sẽ là một ý tưởng tồi khi bắt đầu. Tuy nhiên, truy vấn của bạn thậm chí không tương quan mà không liên quan (không có liên kết đến truy vấn bên ngoài) và dường như trả về nhiều hàng. Điều này dẫn đến (có thể rất tốn kém và vô nghĩa) tham gia chéo để sản xuất một sản phẩm cacte, có thể không phải là ý định (bí mật) của bạn.
Có vẻ như bạn thực sự muốn:
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);
Cả LEFT JOIN
cũng vô nghĩa. Một trong những sale
buộc phải tham gia INNER JOIN
theo điều kiện WHERE. Cái trên mat có vẻ vô nghĩa, vì bạn GROUP BY mat.mat
- ngoại trừ nếu bạn quan tâm đến mat IS NULL
? (Tôi nghi ngờ điều đó.)
Trường hợp này có thể được đơn giản hóa thêm thành:
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
điều kiện có thể được đơn giản hóa hơn nữa, tùy thuộc vào các loại dữ liệu và chỉ số bí mật của bạn. Một lượng thông tin chính xác về trường hợp đó trong câu trả lời liên quan này trên dba.SE
.