Mysql 使用left join和group by组合来自同一个表的两个查询
假设我有下表:Mysql 使用left join和group by组合来自同一个表的两个查询,mysql,join,group-by,Mysql,Join,Group By,假设我有下表: brand | model | country | sales | year | month --------|---------|----------|-------|--------|------- brand1 | model1 | US | 10 | 2017 | 5 brand1 | model2 | US | 11 | 2017 | 5 brand2 | model1 | US | 5
brand | model | country | sales | year | month
--------|---------|----------|-------|--------|-------
brand1 | model1 | US | 10 | 2017 | 5
brand1 | model2 | US | 11 | 2017 | 5
brand2 | model1 | US | 5 | 2017 | 5
brand2 | model2 | US | 18 | 2017 | 5
brand3 | model1 | US | 8 | 2017 | 5
brand3 | model2 | US | 12 | 2017 | 5
brand1 | model1 | US | 80 | 2016 | 5
brand1 | model2 | US | 21 | 2016 | 5
brand2 | model1 | US | 35 | 2016 | 5
brand2 | model2 | US | 25 | 2016 | 5
brand3 | model1 | US | 5 | 2016 | 5
brand3 | model2 | US | 2 | 2016 | 5
brand1 | model1 | DE | 5 | 2017 | 5
brand1 | model1 | DE | 5 | 2017 | 4
brand3 | model2 | P | 2 | 2016 | 5
我想以降序显示特定年份(2017年)特定月份(5)每个品牌在特定国家(美国)的总销售额。这是我写的查询:
$country = str_replace ('-', '[- ]', $_GET['country']);
$year = $_GET['year'];
$month = $_GET['month'];
$previousyear = $year - 1;
$sql = "SELECT brand, SUM(sales) as sumsales
FROM `exampletable`
WHERE country REGEXP :country AND year = :year AND month = :month
GROUP BY brand ORDER BY sumsales DESC";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(":country", $country);
$stmt->bindParam(":year", $year);
$stmt->bindParam(":month", $month);
$stmt->execute();
...
然后,我想在结果中再添加一列,显示去年(2016年)同一个月(5)同一国家的每个品牌的销售数据会很好。我尝试使用左连接来实现这一点,但您会注意到,我开发这些类型查询的知识还不够好…:
$sql = "SELECT a.brand, SUM(a.sales) as asumsales, SUM(b.sales) as bsumsales FROM exampletable a
LEFT JOIN exampletable b on a.brand = b.brand
WHERE a.country REGEXP :country AND b.country REGEXP :country AND a.year = :year AND b.year = :previousyear AND a.month = :month AND b.month = :month
GROUP BY brand ORDER BY asumsales DESC";
预期结果:
brand | sales US, 2017, 5 | sales US, 2016, 5
--------|-------------------|-------------------
brand2 | 23 | 60
brand1 | 22 | 101
brand3 | 20 | 7
我怎样才能得到这个结果?非常感谢您的帮助。如果您使用条件聚合,那么您可以在单个查询中完成此操作:
SELECT
brand,
SUM(CASE WHEN year = 2017 AND month 5 THEN sales ELSE 0 END) AS sumsales1,
SUM(CASE WHEN year = 2016 AND month 5 THEN sales ELSE 0 END) AS sumsales2
FROM exampletable
WHERE country = 'US'
GROUP BY brand
请注意,您可以为所需的两个总和中的每一个将两个子查询连接在一起,但这将是更困难的方法。如果使用条件聚合,则可以在单个查询中执行此操作:
SELECT
brand,
SUM(CASE WHEN year = 2017 AND month 5 THEN sales ELSE 0 END) AS sumsales1,
SUM(CASE WHEN year = 2016 AND month 5 THEN sales ELSE 0 END) AS sumsales2
FROM exampletable
WHERE country = 'US'
GROUP BY brand
请注意,您可以为所需的两个总和中的每一个将两个子查询连接在一起,但这将是更困难的方法。使用条件聚合。在您的情况下,这看起来像:
SELECT brand,
SUM(CASE WHEN year = :year THEN sales ELSE 0 END) as sales_curr,
SUM(CASE WHEN year = :year - 1 THEN sales ELSE 0 END) as sales_prev
FROM exampletable
WHERE country REGEXP :country AND
year IN (:year, :year - 1) AND
month = :month
GROUP BY brand
ORDER BY sales_curr DESC;
使用条件聚合。在您的情况下,这看起来像:
SELECT brand,
SUM(CASE WHEN year = :year THEN sales ELSE 0 END) as sales_curr,
SUM(CASE WHEN year = :year - 1 THEN sales ELSE 0 END) as sales_prev
FROM exampletable
WHERE country REGEXP :country AND
year IN (:year, :year - 1) AND
month = :month
GROUP BY brand
ORDER BY sales_curr DESC;
谢谢你的帮助!这确实是我一直在寻找的答案,但由于蒂姆是第一个提出这个解决方案的人,我接受了他的答案,认为他是正确的。@Stan。我非常尊重Tim,但是我回答了,因为他的回答没有使用参数。谢谢你的帮助!这确实是我一直在寻找的答案,但由于蒂姆是第一个提出这个解决方案的人,我接受了他的答案,认为他是正确的。@Stan。我非常尊重蒂姆,但我回答了,因为他的回答没有使用参数。