Tsql 子查询直接从Query读取行,而不是从Grouped读取行,因此最后两个CTE在某种程度上是彼此的替换,当不再需要时,可以删除Grouped。不要忘记在主选择中取消注释Pivoted(并注释掉Grouped),以实际查看它返回的内容 这个问题对你来说可能很

Tsql 子查询直接从Query读取行,而不是从Grouped读取行,因此最后两个CTE在某种程度上是彼此的替换,当不再需要时,可以删除Grouped。不要忘记在主选择中取消注释Pivoted(并注释掉Grouped),以实际查看它返回的内容 这个问题对你来说可能很,tsql,Tsql,子查询直接从Query读取行,而不是从Grouped读取行,因此最后两个CTE在某种程度上是彼此的替换,当不再需要时,可以删除Grouped。不要忘记在主选择中取消注释Pivoted(并注释掉Grouped),以实际查看它返回的内容 这个问题对你来说可能很难,因为对你来说它是一个复杂的问题:你知道如何旋转,但你不知道如何旋转,我认为这是因为你不知道旋转什么。你可以从一个“普通”组开始,通过查询,以年、月、数的形式返回结果,只是为了确保你能够实现必要的聚合,然后再继续旋转结果。这似乎是我已经拥有的

子查询直接从
Query
读取行,而不是从
Grouped
读取行,因此最后两个CTE在某种程度上是彼此的替换,当不再需要时,可以删除
Grouped
。不要忘记在主选择中取消注释
Pivoted
(并注释掉
Grouped
),以实际查看它返回的内容


这个问题对你来说可能很难,因为对你来说它是一个复杂的问题:你知道如何旋转,但你不知道如何旋转,我认为这是因为你不知道旋转什么。你可以从一个“普通”组开始,通过查询,以
年、月、数的形式返回结果,只是为了确保你能够实现必要的聚合,然后再继续旋转结果。这似乎是我已经拥有的,它可以工作,但只旋转一个日期。对于这个特定场景,我需要确定一个范围内的日期。因此,对于给定的日期范围:2001年11月至2002年3月,轴心应计算2001年11月、12月和2002年1月、2月、3月“单元格”中的5个月。抱歉,如果这不清楚(或者我误解了你),谢谢你,贝丝。你的回答给了我足够的灵感来解决这个问题。我认为拉尔夫·希林顿正在证明相反的观点,即迭代方法是可以避免的。另一方面,
INSERT的
WHERE
条件。。。在循环中选择
(与将
@dateTimePtr
截断为月份这一事实相关)似乎意味着任何范围的
ServiceContractRiskStart
ServiceContractRiskEnd
始终交叉或包括一个月的第一个月。是吗?谢谢你,安德烈。Ralph的答案只适用于单个固定时间点,所以你是对的,这种方法不需要迭代方法。然而,要获得两个日期之间的每个数据点(本例中为月),似乎需要迭代方法。我可能错了,我正在通过这个学习T-SQL!关于月1日因素,我知道起始期必须在第一个月结束时。这基本上是伪代码,直到我重新开始工作并将其平滑+不过,现场1人!
         1     2     3    4    5    6    7    8    9    10    11    12
2000   123   123   123  123  123  123  123  123  123   123   123   123
2001   123   123   123  123  123  123  123  123  123   123   123   123
2002   123   123   123  123  123  123  123  123  123   123   123   123
2003   123   123   123  123  123  123  123  123  123   123   123   123
select y, [1] as January,
            [2] as February, 
            [3] as March,
            [4] as April, 
            [5] as May, 
            [6] as June, 
            [7] as July, 
            [8] as August, 
            [9] as September, 
            [10] as October, 
            [11] as November, 
[12] as December 
from  (select ord_num, 
        DATEPART(year,ord_date)as y,
        DATEPART(month, ord_date) as m from sales) as p
 pivot (count(ord_num) for m in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) as pvt
 order by pvt.y
ALTER PROCEDURE [dbo].[usp_ssis_sa_yr] 
AS
BEGIN
    declare @yr int
    declare @mo int
    declare @i int
    declare @moStart datetime
    declare @nextMoStart datetime

    delete from serviceagreement_year

    set @i = 1
    while @i < 6
    begin
        set @yr =  year(getdate()) - @i
        set @mo = 1
        while @mo < 13
        begin
            set @moStart =  cast(cast(@mo as char(2)) + '/1/' + cast(@yr as char(4)) as datetime)
            set @nextMoStart =  dateadd(m,1,@mostart)

            insert into serviceagreement_year
            SELECT     SANumber, @yr AS yr, @mo as mo
            FROM         dbo.ServiceAgreement sa ...        
            WHERE     (DateFrom < @nextMoStart) AND (DateTo >= @moStart)
            set @mo = @mo + 1
        end
        set @i = @i + 1
    end
create procedure sp_MIS_mySP 
    @fromDate datetime=null,
    @toDate datetime=null,
    @debug int=0
as 

-- get overall date range
declare @firstDate datetime
declare @lastDate datetime

select top 1 @firstDate=Start from MIS_Policies where (@fromDate is null or Start>=@fromDate) order by Start
select top 1 @lastDate=End from MIS_Policies where (@toDate is null or End<=@toDate) order by End desc

if @debug=1
begin
    print 'Parameters:'
    if (@fromDate is null) print '   @fromDate=NULL' else print '   @fromDate='''+rtrim(convert(varchar,@fromDate))+''''
    if (@toDate is null) print '   @toDate=NULL' else print '   @toDate='''+rtrim(convert(varchar,@toDate))+''''
    print 'Evaluated:'
    print '   @firstDate='''+rtrim(convert(varchar,@firstDate))+''''
    print '   @lastDate='''+rtrim(convert(varchar,@lastDate))+''''
end

-- step through date range by month
--   inserting count of active contracts at that point
declare @dateTImePtr datetime
set @dateTImePtr=dateadd(d,-(datepart(d,@firstDate)-1),@firstDate)

declare @startOfMonthPtr datetime
declare @endOfMonthPtr datetime

create table #yearMonthActiveBreakdown (
    [year] int,
    [month] int,
    [count] int)

while @dateTImePtr<=@lastDate
begin
    set @startOfMonthPtr=@dateTImePtr
    set @endOfMonthPtr=DATEADD(m,1,@startOfMonthPtr)
    set @endOfMonthPtr=DATEADD(d,-1,@endOfMonthPtr)

    if @debug=1
    begin
        print '@dateTimePtr='''+rtrim(convert(varchar,@dateTimePtr))+''' (@startOfMonthPtr='''+rtrim(convert(varchar,@startofMonthPtr))+''', @endOfMonthPtr='''+rtrim(convert(varchar,@endOfMonthPtr))+''')'
    end

    -- insert row for year/month aggregating by count of items
    insert into #yearMonthActiveBreakdown ([year],[month],[count]) 
        select year(@dateTImePtr),
            MONTH(@dateTImePtr),
            COUNT(ContractNumber) 
            from MIS_Policies 
            where 
                Start<=@endOfMonthPtr and End>=@startOfMonthPtr and Status in (0,3,4,5)     

    set @dateTImePtr=DATEADD(m,1,@dateTimePtr)

end

if @debug = 1
begin
    -- pre-pivot
    select * from #yearMonthActiveBreakdown
end

select [YEAR],[1] as [Exposure_1],[2] as [Exposure_2],[3] as [Exposure_3],[4] as [Exposure_4],[5] as [Exposure_5],[6] as [Exposure_6],[7] as [Exposure_7],[8] as [Exposure_8],[9] as [Exposure_9],[10] as [Exposure_10],[11] as [Exposure_11],[12] as [Exposure_12]
from (
select [Year],[Month],[Count]
from #yearMonthActiveBreakdown p
) as s
pivot (sum([Count])
for [Month] in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) as pivoted

drop table #yearMonthActiveBreakdown
;
WITH
  QueryPeriod AS (
    SELECT
      Start = DATEADD(M, DATEDIFF(M, 0, MIN(Start)), 0),
      [End] = DATEADD(D, -1, DATEADD(M, DATEDIFF(M, 0, MAX([End])) + 1, 0))
    FROM MIS_Policies
    WHERE (@fromDate IS NULL OR Start >= @fromDate)
      AND (@toDate   IS NULL OR [End] >= @toDate  )
  ),
  Months AS (
    SELECT
      Start = DATEADD(M, v.number, p.Start),
      [End] = DATEADD(D, -1, DATEADD(M, v.number + 1, p.Start))
    FROM QueryPeriod p
      INNER JOIN master..spt_values v
        ON v.number BETWEEN 0 AND DATEDIFF(M, p.Start, p.[End])
    WHERE v.type = 'P'
  ),
  Query AS (
    SELECT
      [Year]  = YEAR (m.Start),
      [Month] = MONTH(m.Start),
      ContractNumber
    FROM MIS_Policies p
      INNER JOIN Months m ON p.Start <= m.[End]
                         AND p.[End] >= m.Start
    WHERE Status IN (0, 3, 4, 5)
  ),
  Grouped AS (
    SELECT
      [Year],
      [Month],
      [Count] = COUNT(ContractNumber)
    FROM Query
    GROUP BY
      [Year],
      [Month]
  ),
  Pivoted AS (
    SELECT
      [Year],
      Exposure_1  = [1],
      Exposure_2  = [2],
      Exposure_3  = [3],
      Exposure_4  = [4],
      Exposure_5  = [5],
      Exposure_6  = [6],
      Exposure_7  = [7],
      Exposure_8  = [8],
      Exposure_9  = [9],
      Exposure_10 = [10],
      Exposure_11 = [11],
      Exposure_12 = [12]
    FROM Query
    PIVOT (
      COUNT(ContractNumber) FOR [Month] IN (
        [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]
      )
    ) p
  )
SELECT *
FROM Grouped /* Pivoted */