1

有点难以解释,我的 SQL Server 不是最好的,但在这里什么都可以。

首先,创建一些表:

CREATE TABLE [dbo].[Quarterly](
[QuarterDate] [datetime] NOT NULL,
[SomeText] [nvarchar](50) NULL,
CONSTRAINT [PK_Quarterly] PRIMARY KEY CLUSTERED 
(
[QuarterDate] ASC
)
GO

CREATE TABLE [dbo].[TmpDegreeDays](
[Date] [datetime] NOT NULL,
[Value] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_TmpDegreeDays] PRIMARY KEY CLUSTERED 
(
[Date] ASC
)
GO

然后插入一些数据:

INSERT [dbo].[Quarterly] ([QuarterDate], [SomeText]) VALUES (CAST(0x00009CF100000000 AS DateTime), N'Blah')
INSERT [dbo].[Quarterly] ([QuarterDate], [SomeText]) VALUES (CAST(0x00009D4B00000000 AS DateTime), N'Fools')
INSERT [dbo].[Quarterly] ([QuarterDate], [SomeText]) VALUES (CAST(0x00009DA600000000 AS DateTime), N'Later')
INSERT [dbo].[Quarterly] ([QuarterDate], [SomeText]) VALUES (CAST(0x00009E0400000000 AS DateTime), N'Something')
INSERT [dbo].[Quarterly] ([QuarterDate], [SomeText]) VALUES (CAST(0x00009E5E00000000 AS DateTime), N'New year')
INSERT [dbo].[Quarterly] ([QuarterDate], [SomeText]) VALUES (CAST(0x00009EC300000000 AS DateTime), N'In april')

然后将日期范围从2010-01-01到(包括)2012-03-10插入到表中TmpDegreeDays

最后:

我想为结果集中当前记录和下一条记录之间的表中TmpDegreeDays的每条记录计算 [Value] 的总和。QuarterlyQuarterDateQuarterly

就像是:

DECLARE @startDate datetime, @endDate datetime
SET @startDate = '2010-01-01'
SET @endDate = '2010-12-31'

SELECT q.QuarterDate, q.SomeText, CustomSum = 
(SELECT SUM(CAST([Value] AS float))
FROM TmpDegreeDays 
WHERE [date] >= q.QuarterDate AND *Current QuarterDate* < *Some query here to get next row QuarterDate*)

FROM Quarterly q

WHERE q.QuarterDate BETWEEN @startDate AND @endDate

我正在寻找的最终输出示例:

2010-01-01   Sum of [Value] between 2010-01-01 and 2010-03-31
2010-04-01   Sum of [Value] between 2010-04-01 and 2010-06-30
2010-07-01   Sum of [Value] between 2010-07-01 and 2010-09-31
2010-10-03   Sum of [Value] between 2010-10-03 and 2010-10-03

这有意义吗?

4

1 回答 1

1

您可以尝试这样的事情 - 使用 CTE(在 SQL Server 2005和更高版本中可用)来查找每个季度的日期,然后总结学位值:

;WITH QuarterlyDates AS
(        
   SELECT 
       QuarterDate, 
       QuarterEndDate = DATEADD(MILLISECOND, -3, DATEADD(MONTH, 3, QuarterDate))
   FROM [dbo].[Quarterly]
)
SELECT
    qd.QuarterDate, qd.QuarterEndDate,
    DegreeSum = (SELECT SUM(DegreeValue) 
                 FROM [dbo].[TmpDegreeDays] 
                 WHERE [Date] BETWEEN qd.QuarterDate AND qd.QuarterEndDate)
FROM
    QuarterlyDates qd

The strange function to determine the QuarterEndDate is rooted in the fact that the DATETIME has a precision of 3.33ms in SQL Server. Thus, the last date for a given month is the last day of that month, and the time is 23:59:59.997 (not .999). Therefore, I need to add three months to the quarter's start date, and then subtract 3 milliseconds from that start date of the next quarter to get the last millisecond of this quarter in question.

Update: OK, in order to get the start and end date for a quarter from the table, you need two nested CTE's in order to determine the "end date of the next quarter minus 3 milliseconds" for the end of the quarter - something like this:

;WITH QuarterStarts AS
(
    SELECT  
        QuarterDate,
        QNumber = ROW_NUMBER() OVER(ORDER BY QuarterDate)   -- ordering number
    FROM [dbo].[Quarterly]
),
Quarters AS
(
    SELECT
        QuarterStartDate = q1.QuarterDate,
        QuarterEndDate = DATEADD(MILLISECOND, -3, q2.QuarterDate) 
    FROM
        QuarterStarts q1
    INNER JOIN 
        QuarterStarts q2 ON q2.QNumber = q1.QNumber + 1 
)
SELECT
    q.QuarterDate, q.QuarterEndDate,
    DegreeSum = (SELECT SUM(DegreeValue) 
                 FROM [dbo].[TmpDegreeDays] 
                 WHERE [Date] BETWEEN q.QuarterDate AND q.QuarterEndDate)
FROM
    Quarters q
于 2012-04-17T21:16:24.803 回答