SQL查询以获取每个产品的月销售额,包括没有销售的产品

Cle*_*ent 4 sql-server

假设我们有一个 Product 表(product_id、product_name)和一个 Sales 表(product_id、date、qty、amount)。

什么 sql 查询会返回每个产品的月销售额,并包括没有销售额的产品

(如果这有什么不同,我正在使用 sql server )。

澄清:我希望每个可能的月份/产品元组都有一行。如果给定月份/产品没有销售额,则应显示零数量/销售额

Sco*_*red 5

看看这是否是您要找的(根据需要调整):

set nocount on

--Declare a months table (or use a Date Dimension table)
Declare @Months Table (MonthNumber tinyint, MonthName varchar(20))
insert into @Months (MonthNumber,MonthName) values
(1,'January'),
(2,'February'),
(3,'March'),
(4,'April'),
(5,'May'),
(6,'June'),
(7,'July'),
(8,'August'),
(9,'September'),
(10,'October'),
(11,'November'),
(12,'December')

--Declare a products table
Declare @Products table (Id int, ProductName Varchar(20)) 
insert into @Products (Id, ProductName)
values(1,'Widgets'),(2,'Thingamabob')

Declare @Sales table (product_id int, [date] Date, qty int, amount decimal(11,2))
insert into @Sales (product_id, [date], qty, amount)
values(1,'2017-01-01',1,100.00),(2,'2017-02-01',1,200.00),(2,'2017-06-01',2,300)

--Select Months and CROSS JOIN to Products, then
--LEFT JOIN to Sales.  Use ISNULL to return zeros
--for months/products with no sales
SELECT m.MONTHNUMBER
    ,m.MonthName
    ,P.ProductName
    ,ISNULL(SUM(QTY), 0) AS QTY
    ,ISNULL(SUM(AMOUNT), 0) AS AMOUNT
FROM @Months m
CROSS JOIN @Products p
LEFT JOIN @Sales s ON DatePart(MONTH, [date]) = M.MonthNumber
    AND S.product_id = P.ID
GROUP BY m.MonthNumber
    ,m.MonthName
    ,P.ProductName
ORDER BY M.MonthNumber
    ,m.MonthName
    ,P.ProductName
Run Code Online (Sandbox Code Playgroud)
| MONTHNUMBER | MonthName | ProductName | QTY | AMOUNT |
|-------------|-----------|-------------|-----|--------|
| 1           | January   | Thingamabob | 0   | 0.00   |
| 1           | January   | Widgets     | 1   | 100.00 |
| 2           | February  | Thingamabob | 1   | 200.00 |
| 2           | February  | Widgets     | 0   | 0.00   |
| 3           | March     | Thingamabob | 0   | 0.00   |
| 3           | March     | Widgets     | 0   | 0.00   |
| 4           | April     | Thingamabob | 0   | 0.00   |
| 4           | April     | Widgets     | 0   | 0.00   |
| 5           | May       | Thingamabob | 0   | 0.00   |
| 5           | May       | Widgets     | 0   | 0.00   |
| 6           | June      | Thingamabob | 2   | 300.00 |
| 6           | June      | Widgets     | 0   | 0.00   |
| 7           | July      | Thingamabob | 0   | 0.00   |
| 7           | July      | Widgets     | 0   | 0.00   |
| 8           | August    | Thingamabob | 0   | 0.00   |
| 8           | August    | Widgets     | 0   | 0.00   |
| 9           | September | Thingamabob | 0   | 0.00   |
| 9           | September | Widgets     | 0   | 0.00   |
| 10          | October   | Thingamabob | 0   | 0.00   |
| 10          | October   | Widgets     | 0   | 0.00   |
| 11          | November  | Thingamabob | 0   | 0.00   |
| 11          | November  | Widgets     | 0   | 0.00   |
| 12          | December  | Thingamabob | 0   | 0.00   |
| 12          | December  | Widgets     | 0   | 0.00   |
Run Code Online (Sandbox Code Playgroud)

注意: OP 没有表示他们想要一个考虑年份的解决方案,所以我的解决方案在聚合数据时没有处理年份的概念。如果月份是 1 月(无论年份如何),则计数进入 1 月存储桶。

更新:为了进一步澄清,我希望每个可能的月份/产品元组都有一行。如果给定月份/产品没有销售额,则应显示零数量/销售额