【问题标题】:SQL Query Summary -SQL 查询摘要 -
【发布时间】:2017-04-05 20:46:08
【问题描述】:

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

这适用于 SQL Server 2012。

考虑一下这个名为 Sales 的数据表

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

将下面的内容变成这样的最佳查询是什么:

*显然数据集不同,但以第二张图片为例。

如果客户的 StartDate 在月份列之前的 OR 范围内并且客户的 EndDate 为空或在月份列之后,则结果中的“活动”状态。

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

想法?想法?例子? 谢谢!

【问题讨论】:

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

标签: sql sql-server tsql reporting


【解决方案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);

退货

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多