2017-04-05 59 views
0

我总是试图编写性能最高的SQL查询,但我一次又一次遇到报告请求,我觉得我不应该成为运行此类查询所需的第一个人并且可能有更好的方法来生成我正在查找的数据集。SQL查询摘要 -

这适用于SQL Server 2012的

考虑数据的这个表,称为销售

​​

在这种情况下,一个单位有一个开始日期和结束日期。结束日期可能为空,因为客户仍在接受服务(例如,考虑基于订阅的产品/服务)。您会注意到,在上述数据中,3位客户已停止服务,5位仍在接受服务。

什么是最佳的查询(一个或多个)写打开下面弄成这个样子:

enter image description here

*明显的数据集是不同的,但作为一个例子第二个图像。

如果客户的StartDate在月份列之前或客户的EndDate为空或在月份列之后,结果中的“活动”状态将为。

- 这可以用大量的内嵌选择(这将是可怕的)完成。 - 也许这可以用T-SQL的PIVOT来完成,但我不清楚上面可能包括StartDate/EndDate逻辑,如何(如果可能)以及它是否会被执行(如果可能)

思考?想法?例子? 谢谢!

+1

首先,你需要你想显示的月份。你可以为此使用一个值子句。然后加入表格,以便获得适用于一个月的记录。然后汇总/每个部门和每月的数据。 (通常,数据透视是在应用程序中完成的,而不是在SQL中完成的:SQL获取数据,该应用程序关心演示文稿。) –

回答

1

如果你正在寻找一个动态透视,请考虑以下

创建一些示例数据

--Drop Table #YourTable 
Create Table #YourTable (CustomerID int,StartDate date,EndDate date,SalesPersonID int,ServicePalnID int,DivisionID int) 
Insert Into #YourTable values 
(1,'2017-01-01','2017-02-06',1,5,1), 
(2,'2017-01-01',null  ,1,5,1), 
(3,'2017-02-04',null  ,1,5,1), 
(4,'2017-02-05','2017-04-05',1,5,2), 
(5,'2017-06-06',null  ,2,6,2), 
(6,'2017-03-26','2017-04-03',2,6,2), 
(7,'2017-04-01',null  ,2,6,3), 
(8,'2017-04-04',null  ,3,6,3) 

动态查询

Declare @Date1 date = '2017-01-01' 
Declare @Date2 date = GetDate() 

Declare @SQL varchar(max) = Stuff((Select ',' + QuoteName(format(D,'MMM yyyy')) 
            From (
              Select Top (DateDiff(MONTH,@Date1,@Date2)+1) 
                D=DateAdd(MONTH,-1+Row_Number() Over (Order By Number),@Date1) 
              From master..spt_values 
             ) A 
            For XML Path('')),1,1,'') 
Select @SQL = ' 
Select [YAxis] as [Division],' + @SQL + ' 
From (
     Select YAxis = concat(''Division '',A.DivisionID) 
       ,XAxis = format(D,''MMM yyyy'') 
       ,Value = 1 
     From #YourTable A 
     Join (
       Select Top (DateDiff(MONTH,'''+concat('',@Date1)+''','''+concat('',@Date2)+''')+1) 
         D=DateAdd(MONTH,-1+Row_Number() Over (Order By Number),'''+concat('',@Date1)+''') 
       From master..spt_values 
      ) B 
      on D between DateFromParts(Year(StartDate),month(StartDate),1) and EOMonth(IsNull(EndDate,GetDate())) 
    ) A 
Pivot (sum(Value) For [XAxis] in (' + @SQL + ')) p' 
Exec(@SQL); 

返回

enter image description here