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。我非常尊重蒂姆,但我回答了,因为他的回答没有使用参数。