SQL-将月份显示为列

时间:2018-08-08 15:56:58

标签: sql-server tsql

我有一个SQL Server表,该合同的日期为Start(1-1-2017)和End(1-1-2022),并且每月和每月都生成当前和过去几个月的发票

即使没有生成发票,我也想将月份显示为列,仅使用SQL / Pivot表或必须创建以日历为日期的表可以吗?

到目前为止,我已经使用此代码。

WITH CTE_MyTable AS
(
     SELECT
         FORMAT(MIN(StartDate), 'yyyy-MM') AS [MyDate] 
     FROM
         MyTable 

     UNION ALL

     SELECT 
         FORMAT(MIN(DATEADD(month, 1, StartDate)), 'yyyy-MM') AS [MyDate] 
     FROM
         MyTable
     WHERE 
         FORMAT(DATEADD(month, 1, StartDate),'yyyy-MM') <= (SELECT FORMAT(MAX(EndDate), 'yyyy-MM') AS [MyDate] FROM MyTable)
)
SELECT [MyDate] 
FROM CTE_ MyTable 
GROUP BY MyDate
OPTION (MAXRECURSION 0);

2 个答案:

答案 0 :(得分:0)

因此,假设您的表如下所示(使用temp变量,因此您只需复制/粘贴/测试即可):

DECLARE @sale TABLE(saledate DATE, saleamt MONEY);
INSERT @sale VALUES ('20170103',500),('20170128',266),('20170303',4002),('20170409',25);

请注意,为简单起见,我只做了6个月。以下查询获取每月销售额(第一个查询)和第二个查询的销售额之和:

DECLARE @sale TABLE(saledate DATE, saleamt MONEY);
INSERT @sale VALUES ('20170103',500),('20170128',266),('20170303',4002),('20170409',25);

SELECT
   [201701] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 1 THEN 1 END),
   [201702] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 2 THEN 1 END),
   [201703] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 3 THEN 1 END),
   [201704] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 4 THEN 1 END),
   [201705] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 5 THEN 1 END),
   [201706] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 6 THEN 1 END)
FROM @sale t;

SELECT
   [201701] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 1 THEN t.saleamt END),0),
   [201702] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 2 THEN t.saleamt END),0),
   [201703] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 3 THEN t.saleamt END),0),
   [201704] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 4 THEN t.saleamt END),0),
   [201705] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 5 THEN t.saleamt END),0),
   [201706] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 6 THEN t.saleamt END),0)
FROM @sale t;

这些查询返回:

201701      201702      201703      201704      201705      201706
----------- ----------- ----------- ----------- ----------- -----------
2           0           1           1           0           0


201701                201702                201703                201704                201705                201706
--------------------- --------------------- --------------------- --------------------- --------------------- ---------------------
766.00                0.00                  4002.00               25.00                 0.00                  0.00

答案 1 :(得分:0)

有一种方法可以使用Pivot()函数在SQL中旋转列(Microsoft文档位于https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017

要将月份显示为列(1至12),Pivot()函数将值分配给(硬编码)列。正确实施后,由于缺少记录,有一些NULL不会发生聚合。用COALESCE()函数隐含用零代替NULL的方法。

应该对数据透视表的年份值进行分组,并且对于数据透视表没有特定的Group By,这由 SourceTable 查询的编写方式暗示。

在此示例代码中,我使用与官方文档相同的确切格式;除了我另外按年份分组并且将COALESCE NULL与0组合在一起。

我正在做的是计算给定月份和年份的记录数:

SELECT yearval
      ,COALESCE([1], 0) [Jan]
      ,COALESCE([2], 0) [Feb]
      ,COALESCE([3], 0) [Mar]
      ,COALESCE([4], 0) [Apr]
      ,COALESCE([5], 0) [May]
      ,COALESCE([6], 0) [Jun]
      ,COALESCE([7], 0) [Jul]
      ,COALESCE([8], 0) [Aug]
      ,COALESCE([9], 0) [Sep]
      ,COALESCE([10], 0) [Oct]
      ,COALESCE([11], 0) [Nov]
      ,COALESCE([12], 0) [Dec]
FROM      
(SELECT YEAR([Your_Date_Column_Here]) AS [yearval]
       ,MONTH([Your_Date_Column_Here]) AS [monthval]           
   FROM [Your_Table_Name_Here]) AS SourceTable
PIVOT
(
  COUNT(monthval) FOR monthval IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])  
) AS PivotTable

将在我的测试数据库中产生以下输出:

yearval Jan    Feb     Mar     Apr     May     Jun     Jul     Aug     Sep     Oct     Nov     Dec
2015    1952   1122    1678    2364    1125    1308    1414    2103    1031    1340    2506    1015    
2016    1123   1413    1568    1421    1278    1252    1048    1290    1251    1571    2647    1253
2017    0      0       0       3       0       1241    2377    2714    6724    1388    1521    1243
2018    2127   2118    2449    2330    2687    3833    3279    883     0       0       0       0