1

上周三开始使用 TSQL ......

我在 tblStage1 中有以下数据:

PROJECT    USERNAME           DATE          PERCENTAGE                  
---------  -----------------  ------------  ---------------------- 
Project 1  DOMAIN\Chris.User  03/01/2013    0.25                     
Project 1  DOMAIN\Chris.User  05/01/2013    0.75                     
Project 1  DOMAIN\Chris.User  07/01/2013    1                     
Project 1  DOMAIN\John.User   02/01/2013    1                     
Project 1  DOMAIN\John.User   06/01/2013    0.5                     

我在 tblRawData 中有以下数据

PROJECT    START_DATE   END_DATE
---------- -----------  ----------
Project 1  01/01/2013   09/01/2013

我想将以下数据输入 tblStage2(数据点由 START_DATE 和 END_DATE 绑定):

PROJECT    USERNAME           DATE          PERCENTAGE                  
---------  -----------------  ------------  ---------------------- 
Project 1  DOMAIN\Chris.User  01/01/2013    0                     
Project 1  DOMAIN\Chris.User  02/01/2013    0                         
Project 1  DOMAIN\Chris.User  03/01/2013    0.25                     
Project 1  DOMAIN\Chris.User  04/01/2013    0.25                      
Project 1  DOMAIN\Chris.User  05/01/2013    0.75                     
Project 1  DOMAIN\Chris.User  06/01/2013    0.75                     
Project 1  DOMAIN\Chris.User  07/01/2013    1                     
Project 1  DOMAIN\Chris.User  08/01/2013    1                     
Project 1  DOMAIN\Chris.User  09/01/2013    1                  
Project 1  DOMAIN\John.User   01/01/2013    0                     
Project 1  DOMAIN\John.User   02/01/2013    1                         
Project 1  DOMAIN\John.User   03/01/2013    1
Project 1  DOMAIN\John.User   04/01/2013    1                      
Project 1  DOMAIN\John.User   05/01/2013    1                     
Project 1  DOMAIN\John.User   06/01/2013    0.5                     
Project 1  DOMAIN\John.User   07/01/2013    0.5                     
Project 1  DOMAIN\John.User   08/01/2013    0.5                     
Project 1  DOMAIN\John.User   09/01/2013    0.5                  

我意识到有许多与此主题相关的主题,例如 this。我的情况是,我没有任何特别的限制,我正在寻找一个相对容易理解的干净的例程。

我知道有一个DateAdd函数,但我没有INSERT INTO在示例语句中看到任何命令。我对如何遍历数据集并创建插值感到困惑。我仍然太年轻,无法理解其他示例的完整背景,并且非常感谢任何帮助或澄清。

编辑向示例数据添加了附加信息,以便更好地指示我的最终目标。我将在这个数据集中有多个用户。USERNAME 列由原始源(InfoPath 表单上的人员选取器)放入数据集中。在分配第一个值之前,所有“百分比”都是“0”,然后它们保留该值,直到它被更改或项目到达其结束日期。我希望这有助于澄清!

4

3 回答 3

2

目前尚不清楚 USERNAME 是如何填充的。我假设您在此处的项目中有相同的用户名。下面的 CTE 只是构建了一个 DATE 表,如果你有自己的 date 表,可以跳过这部分。

SQL小提琴

DECLARE @ENDDate DATETIME

SELECT @ENDDate =  MAX(END_DATE) FROM tblRawData

;WITH tblDate AS 
( SELECT CAST(MIN(START_DATE) AS DATE) AS [date]
  FROM tblRawData 
  UNION ALL
  SELECT DATEADD(month,1,[DATE])
  FROM tblDate
  WHERE [DATE] < @ENDDate
 )
SELECT
  d.[date]
  ,r.[Project]
  ,UserName =   (SELECT MAX(USERNAME) FROM tblStage1 ts WHERE r.PROJECT = ts.PROJECT)
  ,Percentage = (SELECT ISNULL(MAX(Percentage),0) FROM tblStage1 ts WHERE r.PROJECT = ts.PROJECT AND ts.[date] <= d.[date])
FROM tblDate d
INNER JOIN tblRawData r
  ON d.[date] between r.[START_DATE] AND r.[END_DATE]
ORDER BY 2,1
OPTION (Maxrecursion 0) 

编辑: 刚刚发现日期按月增加。我更新了 CTE 查询。但是,您需要确保在该月的第一天拥有所有项目的开始和结束日期。


编辑 基于您的新样品日期。查询现在变得有点难看,但是,它可以工作。我现在想不出更好的解决方案。

新的SQL 提琴手

DECLARE @ENDDate DATETIME

SELECT @ENDDate =  MAX(END_DATE) FROM tblRawData

;WITH tblDate AS 
( SELECT CAST(MIN(START_DATE) AS DATE) AS [date]
  FROM tblRawData 
  UNION ALL
  SELECT DATEADD(month,1,[DATE])
  FROM tblDate
  WHERE [DATE] < @ENDDate
 )
,ProjectList AS (
 SELECT Project,UserName
 FROM tblStage1
 GROUP BY Project,UserName
)
,cte AS (
SELECT
  d.[date]
  ,r.[Project]
  ,UserName = pl.Username
  ,CloseDate = (SELECT MAX(ts.[date]) FROM tblStage1 ts WHERE r.PROJECT = ts.PROJECT AND ts.UserName = pl.UserName AND ts.[date] <= d.[date])
FROM tblDate d
INNER JOIN tblRawData r
  ON d.[date] between r.[START_DATE] AND r.[END_DATE]
CROSS APPLY ProjectList pl
)
SELECT cte.[date],cte.project,cte.UserName,ISNULL(t.[PERCENTAGE],0) AS PERCENTAGE
FROM cte
LEFT JOIN tblStage1 t
 ON cte.PROJECT = t.PROJECT 
  AND cte.UserName = t.UserName  
  AND cte.CloseDate = t.[Date]
ORDER BY 2,3,1
于 2013-05-07T18:09:54.940 回答
1

您也可以使用 APPLY 运算符执行此操作...

WITH DateList (Project, MonthStart) AS
    (
        SELECT 
            project
            , Start_Date
        FROM 
            tblRawData
        UNION ALL
        SELECT 
            dl.Project
            , DATEADD(MONTH, 1, dl.MonthStart)
        FROM 
            DateList dl
        JOIN
            tblRawData r 
            ON 
                r.Project = dl.Project
                AND 
                dl.MonthStart < r.End_Date
    )
SELECT 
    dl.Project
    , lastUser.UserName 
    , dl.monthstart [Date]
    , ISNULL(pct.Percentage, 0) Percentage
FROM 
    DateList dl
CROSS APPLY
    (
        SELECT 
            TOP 1 
            USERNAME
        FROM
            tblStage1 t1
        WHERE 
            t1.Project = dl.Project
        ORDER BY 
            t1.Date DESC
    ) lastUser
OUTER APPLY
    (
        SELECT 
            TOP 1 
            Percentage
        FROM
            tblStage1 t2
        WHERE 
            t2.Project = dl.Project
            AND 
            t2.Date <= dl.MonthStart
        ORDER BY 
            t2.Date DESC
    ) pct
于 2013-05-07T18:16:54.227 回答
0

一个非常简单的方法是创建一个临时表,其中包含您需要的每个月的月份值,然后对该表进行左连接。

出于好奇 - 为什么是 8 月 1 日而不是 0 日?

于 2013-05-07T18:09:20.553 回答