SQL从日期列中提取月份并在JOIN命令中重用

时间:2016-01-29 12:59:18

标签: sql sql-server join common-table-expression

我有一个SQL查询(Microsoft SQL服务器),我在其中从日期列中提取一个月。我想在join命令中重用这个提取的月份,将其用作将结果与另一个表中的另一列连接的标准。

背景是在数据库中使用日历时间,但我需要在财政时间内得到结果。有一个表结合日历时间和财政时间。

从我查询的表中提取月份时,我想将其加入到结婚表的日历月份部分,其中包含会计年度和日历年度日期。该表名为MSP_TimeByDay_OlapView,包含CalendarMemberKeyMonth和FiscalMemberKeyPeriod列。

这样,最后我可以将一个包含会计月份的列添加到结果中,并按此而不是按日历月过滤。

查询有效,但对日历中的字段返回NULL - 财务表:

SELECT 
MSP_EpmProject_UserView.ProjectName,
MSP_EpmResource_UserView.ResourceName,
MSP_EpmResource_UserView.Discipline,
MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay) AS Month,
SUM(MSP_EpmAssignmentByDay_UserView.AssignmentMaterialWork) As Materials,
SUM(MSP_EpmAssignmentByDay_UserView.AssignmentWork) AS Work,
MSP_TimeByDay_OlapView.[CalendarMemberKeyMonth],
MSP_TimeByDay_OlapView.[FiscalMemberKeyPeriod]

FROM MSP_EpmResource_UserView 
     INNER JOIN ((MSP_EpmTask_UserView 
              INNER JOIN MSP_EpmProject_UserView 
          ON MSP_EpmTask_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID) 

                  INNER JOIN MSP_EpmAssignment ON MSP_EpmTask_UserView.ProjectUID = MSP_EpmAssignment.ProjectUID 
          AND MSP_EpmTask_UserView.TaskUID = MSP_EpmAssignment.TaskUID) 

     ON MSP_EpmResource_UserView.ResourceUID = MSP_EpmAssignment.ResourceUID 
     INNER JOIN MSP_EpmAssignmentByDay_UserView 
     ON MSP_EpmAssignment.AssignmentUID = MSP_EpmAssignmentByDay_UserView.AssignmentUID 
     LEFT JOIN MSP_TimeByDay_OlapView
     ON MSP_EpmAssignmentByDay_UserView.[TimeByDay] = MSP_TimeByDay_OlapView.CalendarMemberKeyMonth

WHERE (MSP_EpmAssignmentByDay_UserView.TimeByDay BETWEEN '2016-01-01' AND '2016-12-31') 
GROUP BY
MSP_EpmProject_UserView.ProjectName,
MSP_EpmResource_UserView.ResourceName,
MSP_EpmResource_UserView.Discipline, 
MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay),
MSP_TimeByDay_OlapView.[CalendarMemberKeyMonth],
MSP_TimeByDay_OlapView.[FiscalMemberKeyPeriod]

这不起作用,因为JOIN的倒数第二行不包含SELECT语句中的月份命令。但是,当我添加它时,查询只运行几分钟(所以我取消了它)。这是以下内容:

SELECT 
MSP_EpmProject_UserView.ProjectName,
MSP_EpmResource_UserView.ResourceName,
MSP_EpmResource_UserView.Discipline,
MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay) AS Month,
SUM(MSP_EpmAssignmentByDay_UserView.AssignmentMaterialWork) As Materials,
SUM(MSP_EpmAssignmentByDay_UserView.AssignmentWork) AS Work,
MSP_TimeByDay_OlapView.[CalendarMemberKeyMonth],
MSP_TimeByDay_OlapView.[FiscalMemberKeyPeriod]

FROM MSP_EpmResource_UserView 
     INNER JOIN ((MSP_EpmTask_UserView 
              INNER JOIN MSP_EpmProject_UserView 
          ON MSP_EpmTask_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID) 

                  INNER JOIN MSP_EpmAssignment ON MSP_EpmTask_UserView.ProjectUID = MSP_EpmAssignment.ProjectUID 
          AND MSP_EpmTask_UserView.TaskUID = MSP_EpmAssignment.TaskUID) 

     ON MSP_EpmResource_UserView.ResourceUID = MSP_EpmAssignment.ResourceUID 
     INNER JOIN MSP_EpmAssignmentByDay_UserView 
     ON MSP_EpmAssignment.AssignmentUID = MSP_EpmAssignmentByDay_UserView.AssignmentUID 
     LEFT JOIN MSP_TimeByDay_OlapView
     ON MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay) = MSP_TimeByDay_OlapView.CalendarMemberKeyMonth

WHERE (MSP_EpmAssignmentByDay_UserView.TimeByDay BETWEEN '2016-01-01' AND '2016-12-31') 
GROUP BY
MSP_EpmProject_UserView.ProjectName,
MSP_EpmResource_UserView.ResourceName,
MSP_EpmResource_UserView.Discipline, 
MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay),
MSP_TimeByDay_OlapView.[CalendarMemberKeyMonth],
MSP_TimeByDay_OlapView.[FiscalMemberKeyPeriod]

我已经尝试过实施CTE,但是没有成功,因为我不断遇到多部分标识符无法绑定的错误。

WITH CTE(Ass)
AS
--Define CTE query.
(
SELECT MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay) AS Ass
FROM MSP_EpmAssignmentByDay_UserView
)

--Define outer query.
SELECT 
MSP_EpmProject_UserView.ProjectName,
MSP_EpmResource_UserView.ResourceName,
MSP_EpmResource_UserView.Discipline,
MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay) As Month,
SUM(MSP_EpmAssignmentByDay_UserView.AssignmentMaterialWork) As Materials,
SUM(MSP_EpmAssignmentByDay_UserView.AssignmentWork) AS Work,
MSP_TimeByDay_OlapView.[CalendarMemberKeyMonth],
MSP_TimeByDay_OlapView.[FiscalMemberKeyPeriod],
CTE.Ass

FROM MSP_EpmResource_UserView 
     INNER JOIN ((MSP_EpmTask_UserView 
              INNER JOIN MSP_EpmProject_UserView 
          ON MSP_EpmTask_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID) 

                  INNER JOIN MSP_EpmAssignment ON MSP_EpmTask_UserView.ProjectUID = MSP_EpmAssignment.ProjectUID 
          AND MSP_EpmTask_UserView.TaskUID = MSP_EpmAssignment.TaskUID) 

     ON MSP_EpmResource_UserView.ResourceUID = MSP_EpmAssignment.ResourceUID 
     INNER JOIN MSP_EpmAssignmentByDay_UserView 
     ON MSP_EpmAssignment.AssignmentUID = MSP_EpmAssignmentByDay_UserView.AssignmentUID 
     FULL OUTER JOIN MSP_TimeByDay_OlapView
     ON CTE.Ass = MSP_TimeByDay_OlapView.CalendarMemberKeyMonth

WHERE (MSP_EpmAssignmentByDay_UserView.TimeByDay BETWEEN '2016-01-01' AND '2016-12-31') 
GROUP BY
MSP_EpmProject_UserView.ProjectName,
MSP_EpmResource_UserView.ResourceName,
MSP_EpmResource_UserView.Discipline, 
MONTH(MSP_EpmAssignmentByDay_UserView.TimeByDay),
MSP_TimeByDay_OlapView.[CalendarMemberKeyMonth],
MSP_TimeByDay_OlapView.[FiscalMemberKeyPeriod]

需要CTE吗?

1 个答案:

答案 0 :(得分:0)

我刚刚找到了问题的答案:)

尽管如此,谢谢你们所有人!

添加一行,加入年份,解决了这个问题。 这可能是不可解决的,没有其他时间级别存在的信息 - 我为此道歉,但我没想到这可能是问题。

因此,如果有人试图这样做(使用MS Project Server),添加以下内容会有所帮助:

AND YEAR(MSP_EpmAssignmentByDay_UserView.[TimeByDay]) = MSP_TimeByDay_OlapView.CalendarMemberKeyYear

查询现在非常慢,但确实有效。