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

SQL extract month from date column and reuse in JOIN command

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

背景是数据库中使用日历时间,但我需要财政时间的结果。有一个 table 结合了日历时间和财政时间。

当我从 table 查询中提取月份时,我想将其加入 marry-up-table 的日历月份部分,其中包含财政年度和日历年日期.此 table 名为 MSP_TimeByDay_OlapView 并包含 CalendarMemberKeyMonth 和 FiscalMemberKeyPeriod 列。

这样,最后我可以在结果中添加一个包含财政月份的列,并以此而不是日历月份进行过滤。

查询有效,但日历中的字段 returns 为 NULL - 财政 table:

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 语句中的 Month 命令。但是,当我添加它时,查询只运行了几分钟(所以我取消了它)。这是以下内容:

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?

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

尽管如此,谢谢大家!

加一条线路,加入年号,问题解决。 这可能无法解决,没有其他时间级别也存在的信息 - 对此我深表歉意,但我没想到这可能是问题所在。

所以如果有人试图做同样的事情(使用 MS Project Server),添加以下帮助:

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

现在的查询确实很慢,但确实有效。