2017-06-17 98 views
0

加入和组比方说,我有如下表:来自同一个表合并两个查询使用左边

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(); 
... 

然后,我认为这将是不错的另一列添加到显示每个品牌的销售数字在同一个国家同月(5)去年的结果(2016 )。我试图做到这一点使用left join,但是你会发现我的知识来开发这些类型的查询的只是不够好...:

$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 

哪有我得到这个结果?任何帮助将非常感激。

回答

1

如果您使用条件聚集那么您可以在一个单一的查询做到这一点:

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 

请注意,您可以连接在一起的两个子查询为每个要两个和的,但是这将是更难的方式做到这一点。

+0

谢谢!看起来我正在使这种方式太难... – Stan

1

使用条件聚合。在你的情况下,这看起来像:

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; 
+0

感谢您的帮助!这确实是我正在寻找的答案,但是随着蒂姆第一个想出这个解决方案,我接受了他的答案作为正确答案。 – Stan

+0

@Stan。 。 。我非常尊重蒂姆,但我回答是因为他的回答不使用参数。 –