用SQL对子集求和
我有两张这样的桌子:用SQL对子集求和,sql,sql-server,Sql,Sql Server,我有两张这样的桌子: | SalesId | SalesDate | SalesStore | | StoreId | Name | |---------|-----------|------------| |---------|---------| | 1 | 5/3/17 | 3 | | 1 | Store A | | 2 | 2/2/18 | 3
| SalesId | SalesDate | SalesStore | | StoreId | Name |
|---------|-----------|------------| |---------|---------|
| 1 | 5/3/17 | 3 | | 1 | Store A |
| 2 | 2/2/18 | 3 | | 2 | Store B |
| 3 | 6/6/17 | 2 | | 3 | Store C |
| 4 | 7/8/17 | 3 |
我想知道是否可以仅使用SQL生成以下输出:
| Year | Store A | Store B | Store C |
|---------|---------|---------|---------|
| 2017 | 0 | 1 | 2 |
| 2018 | 0 | 0 | 1 |
基本上我想要的是每年每家商店的销售额总和
我能够通过以下方式获得所有门店的总数:
SELECT YEAR(SalesDate) [Year], Count(1) [Sales Count]
FROM Sales
GROUP BY YEAR(SalesDate)
ORDER BY 1
但是我想知道是否可以使用一个SQL查询来实现这一点 我通过为每年创建一个
PIVOT
表,然后使用UNION
将它们组合在一起,实现了这一目标
SELECT '2017' AS 'Year',[Store A],[Store B],[Store C]
FROM
(
SELECT YEAR(Sales.SalesDate) 'SalesYear',Store.[Name]
FROM Sales
JOIN Store ON Sales.SalesStore = StoreId
WHERE YEAR(Sales.SalesDate) = 2017) AS table2017
PIVOT
(
COUNT(SalesYear)
FOR [Name] IN ([Store A],[Store B],[Store C])
) AS pivotTable2017
UNION
SELECT '2018' AS 'Year',[Store A],[Store B],[Store C]
FROM
(
SELECT YEAR(Sales.SalesDate) 'SalesYear',Store.[Name]
FROM Sales
JOIN Store ON Sales.SalesStore = StoreId
WHERE YEAR(Sales.SalesDate) = 2018)AS table2018
PIVOT
(
COUNT(SalesYear)
FOR [Name] IN ([Store A],[Store B],[Store C])
) AS pivotTable2018
结果
+------+----------+----------+---------+
| Year | Store A | Store B | Store C |
+------+----------+----------+---------+
| 2017 | 0 | 1 | 2 |
| 2018 | 0 | 0 | 1 |
+------+----------+----------+---------+
这是一个动态交叉表解决方案,可以处理任意数量的商店
IF OBJECT_ID('tempdb..#Store', 'U') IS NOT NULL
DROP TABLE #Store;
CREATE TABLE #Store (
StoreId INT NOT NULL PRIMARY KEY,
StoreName CHAR(7) NOT NULL
);
INSERT #Store (StoreId, StoreName) VALUES (1, 'Store A'), (2, 'Store B'), (3, 'Store C');
IF OBJECT_ID('tempdb..#Sales', 'U') IS NOT NULL
DROP TABLE #Sales;
CREATE TABLE #Sales (
SalesId INT NOT NULL PRIMARY KEY,
SalesDate DATE NOT NULL,
SalesStore INT NOT NULL
);
INSERT #Sales (SalesId, SalesDate, SalesStore) VALUES
(1, '2017-05-03', 3), (2, '2018-02-02', 3),
(3, '2017-06-06', 2), (4, '2017-07-08', 3);
--SELECT * FROM #Store st;
--SELECT * FROM #Sales s;
--=========================================================
DECLARE
@StoreCols VARCHAR(8000) = '',
@sql VARCHAR(8000) = '',
@DeBug BIT = 0;
SELECT
@StoreCols = CONCAT(@StoreCols, ',
[', st.StoreName, '] = COUNT(CASE WHEN s.SalesStore = ', st.StoreId, ' THEN 1 END)')
FROM
#Store st
ORDER BY
st.StoreId;
SET @sql = CONCAT('
SELECT
[Year] = YEAR(s.SalesDate)',
@StoreCols, '
FROM
#Sales s
GROUP BY
YEAR(s.SalesDate);')
IF @DeBug = 1
BEGIN
PRINT(@sql);
END
ELSE
BEGIN
EXEC(@sql);
END;
结果
Year Store A Store B Store C
----------- ----------- ----------- -----------
2017 0 1 2
2018 0 0 1
嗯,Jason可能必须阅读PIVOT查询如果SalesStore的数量不固定,您需要PIVOT或dynamic PIVOT。这里可以找到很多答案。如果是固定数量的存储,则可以使用条件聚合。如果不是的话,就像人们在我之前所说的,PIVOT是一个不错的选择。谢谢大家,我会搜索PIVOT表的。。。