显示每个位置的月差距
Display Month Gaps for Each location
我有以下查询,它接收 opps 并计算每个月的持续时间和收入。但是,对于某些没有数据的位置,它会丢失几个月。本质上,我希望每个位置和记录类型都显示所有月份。我在日历上尝试了左外连接,但这似乎也没有用。
这里是查询:
;With DateSequence( [Date] ) as
(
Select CAST(@fromdate as DATE) as [Date]
union all
Select CAST(dateadd(day, 1, [Date]) as Date)
from DateSequence
where Date < @todate
)
INSERT INTO CalendarTemp (Date, Day, DayOfWeek, DayOfYear, WeekOfYear, Month, MonthName, Year)
Select
[Date] as [Date],
DATEPART(DAY,[Date]) as [Day],
DATENAME(dw, [Date]) as [DayOfWeek],
DATEPART(DAYOFYEAR,[Date]) as [DayOfYear],
DATEPART(WEEK,[Date]) as [WeekOfYear],
DATEPART(MONTH,[Date]) as [Month],
DATENAME(MONTH,[Date]) as [MonthName],
DATEPART(YEAR,[Date]) as [Year]
from DateSequence option (MaxRecursion 10000)
;
DELETE FROM CalendarTemp WHERE DayOfWeek IN ('Saturday', 'Sunday');
SELECT
AccountId
,AccountName
,Office
,Stage = (CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
,Id
,Name
,RecordType= (CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,Start_Date
,End_Date
,Probability
,Estimated_Revenue_Won = ISNULL(Amount, 0)
,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Name) AS Row
--,Revenue_Per_Day = CAST(ISNULL(Amount/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0),0) as money)
,YEAR(c.Date) as year
,MONTH(c.Date) as Month
,c.MonthName
--, ISNULL(CAST(Sum((Amount)/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0)) as money),0) As RevenuePerMonth
FROM SF_Extracted_Opps o
LEFT OUTER JOIN CalendarTemp c on o.Start_Date <= c.Date AND o.End_Date >= c.Date
WHERE
Start_Date <= @todate AND End_Date >= @fromdate
AND Office IN (@Location)
AND recordtypeid IN ('LAS1')
GROUP BY
AccountId
,AccountName
,Office
,(CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
,Id
,Name
,(CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,Amount
--, CAST(ISNULL(Amount/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0),0) as money)
,Start_Date
,End_Date
,Probability
,YEAR(c.Date)
,Month(c.Date)
,c.MonthName
,dbo.CalculateNumberOFWorkDays(Start_Date, End_Date)
ORDER BY Office
, (CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,(CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
, [Start_Date], Month(c.Date), AccountName, Row;
我尝试向此添加另一个左外部联接并使用此子查询和基本上基于年和月的日历上的联接,但这似乎也不起作用。建议将不胜感激。
--Date Calendar for each location:
;With DateSequence( [Date], Locatio) as
(
Select CAST(@fromdate as DATE) as [Date], oo.Office as location
union all
Select CAST(dateadd(day, 1, [Date]) as Date), oo.Office as location
from DateSequence dts
join Opportunity_offices oo on 1 = 1
where Date < @todate
)
--select result
INSERT INTO CalendarTemp (Location,Date, Day, DayOfWeek, DayOfYear, WeekOfYear, Month, MonthName, Year)
Select
location,
[Date] as [Date],
DATEPART(DAY,[Date]) as [Day],
DATENAME(dw, [Date]) as [DayOfWeek],
DATEPART(DAYOFYEAR,[Date]) as [DayOfYear],
DATEPART(WEEK,[Date]) as [WeekOfYear],
DATEPART(MONTH,[Date]) as [Month],
DATENAME(MONTH,[Date]) as [MonthName],
DATEPART(YEAR,[Date]) as [Year]
from DateSequence option (MaxRecursion 10000)
;
如果您想要来自 CalendarTemp 的所有记录并且只有来自 SF_Extracted_Opps 的记录,则您的 LEFT JOIN 向后,那么您的 CalendarTemp 应该是 LEFT 的 table。但是,您可以将 LEFT JOIN 切换为 RIGHT JOIN,它应该已修复。另一个问题是您的 WHERE 语句正在使用 SF_Extracted_Opps table 中的列,这只会使它再次成为 INNER JOIN。
这是一种修复方法。
SELECT
.....
FROM
CalendarTemp c
LEFT JOIN SF_Extracted_Opps o
ON o.Start_Date <= c.Date AND o.End_Date >= c.Date
AND o.Start_Date <= @todate AND End_Date >= @fromdate
AND o.Office IN (@Location)
AND o.recordtypeid IN ('LAS1')
您可能 运行 遇到的另一个问题是因为您从 CalendarTemp Table 中删除了周末 Table 并非所有日期都显示了 我会测试周末是否仍然存在,看看是否有所不同结果。
这一行:
AND o.Start_Date <= @todate AND End_Date >= @fromdate
也不需要,因为您已经限制了前一行的日期和 CalendarTempTable
中的值
关于您的 CalendarDate 的注释 table 您不必返回并删除这些记录,只需将星期几添加为 select 上的 WHERE 语句即可填充 table.
编辑所有办公室,您可以使用您的办公室 table 与您的 CalendarTemp table 的交叉连接来执行此操作,在您的最终查询中执行此操作,而不是在构建日历的 cte 中执行此操作。在 CTE 日历定义中这样做的问题在于它是递归的,因此您必须在锚点和递归成员定义中都这样做。
SELECT
.....
FROM
CalendarTemp c
CROSS JOIN Opportunity_offices oo
LEFT JOIN SF_Extracted_Opps o
ON o.Start_Date <= c.Date AND o.End_Date >= c.Date
AND o.Start_Date <= @todate AND End_Date >= @fromdate
AND oo.office = o.Office
AND o.recordtypeid IN ('LAS1')
我有以下查询,它接收 opps 并计算每个月的持续时间和收入。但是,对于某些没有数据的位置,它会丢失几个月。本质上,我希望每个位置和记录类型都显示所有月份。我在日历上尝试了左外连接,但这似乎也没有用。
这里是查询:
;With DateSequence( [Date] ) as
(
Select CAST(@fromdate as DATE) as [Date]
union all
Select CAST(dateadd(day, 1, [Date]) as Date)
from DateSequence
where Date < @todate
)
INSERT INTO CalendarTemp (Date, Day, DayOfWeek, DayOfYear, WeekOfYear, Month, MonthName, Year)
Select
[Date] as [Date],
DATEPART(DAY,[Date]) as [Day],
DATENAME(dw, [Date]) as [DayOfWeek],
DATEPART(DAYOFYEAR,[Date]) as [DayOfYear],
DATEPART(WEEK,[Date]) as [WeekOfYear],
DATEPART(MONTH,[Date]) as [Month],
DATENAME(MONTH,[Date]) as [MonthName],
DATEPART(YEAR,[Date]) as [Year]
from DateSequence option (MaxRecursion 10000)
;
DELETE FROM CalendarTemp WHERE DayOfWeek IN ('Saturday', 'Sunday');
SELECT
AccountId
,AccountName
,Office
,Stage = (CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
,Id
,Name
,RecordType= (CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,Start_Date
,End_Date
,Probability
,Estimated_Revenue_Won = ISNULL(Amount, 0)
,ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Name) AS Row
--,Revenue_Per_Day = CAST(ISNULL(Amount/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0),0) as money)
,YEAR(c.Date) as year
,MONTH(c.Date) as Month
,c.MonthName
--, ISNULL(CAST(Sum((Amount)/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0)) as money),0) As RevenuePerMonth
FROM SF_Extracted_Opps o
LEFT OUTER JOIN CalendarTemp c on o.Start_Date <= c.Date AND o.End_Date >= c.Date
WHERE
Start_Date <= @todate AND End_Date >= @fromdate
AND Office IN (@Location)
AND recordtypeid IN ('LAS1')
GROUP BY
AccountId
,AccountName
,Office
,(CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
,Id
,Name
,(CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,Amount
--, CAST(ISNULL(Amount/NULLIF(dbo.CalculateNumberOFWorkDays(Start_Date, End_Date),0),0) as money)
,Start_Date
,End_Date
,Probability
,YEAR(c.Date)
,Month(c.Date)
,c.MonthName
,dbo.CalculateNumberOFWorkDays(Start_Date, End_Date)
ORDER BY Office
, (CASE
WHEN recordtypeid = 'LAS1' THEN 'S'
END)
,(CASE WHEN StageName = 'Closed Won' THEN 'Closed Won'
ELSE 'Open'
END)
, [Start_Date], Month(c.Date), AccountName, Row;
我尝试向此添加另一个左外部联接并使用此子查询和基本上基于年和月的日历上的联接,但这似乎也不起作用。建议将不胜感激。
--Date Calendar for each location:
;With DateSequence( [Date], Locatio) as
(
Select CAST(@fromdate as DATE) as [Date], oo.Office as location
union all
Select CAST(dateadd(day, 1, [Date]) as Date), oo.Office as location
from DateSequence dts
join Opportunity_offices oo on 1 = 1
where Date < @todate
)
--select result
INSERT INTO CalendarTemp (Location,Date, Day, DayOfWeek, DayOfYear, WeekOfYear, Month, MonthName, Year)
Select
location,
[Date] as [Date],
DATEPART(DAY,[Date]) as [Day],
DATENAME(dw, [Date]) as [DayOfWeek],
DATEPART(DAYOFYEAR,[Date]) as [DayOfYear],
DATEPART(WEEK,[Date]) as [WeekOfYear],
DATEPART(MONTH,[Date]) as [Month],
DATENAME(MONTH,[Date]) as [MonthName],
DATEPART(YEAR,[Date]) as [Year]
from DateSequence option (MaxRecursion 10000)
;
如果您想要来自 CalendarTemp 的所有记录并且只有来自 SF_Extracted_Opps 的记录,则您的 LEFT JOIN 向后,那么您的 CalendarTemp 应该是 LEFT 的 table。但是,您可以将 LEFT JOIN 切换为 RIGHT JOIN,它应该已修复。另一个问题是您的 WHERE 语句正在使用 SF_Extracted_Opps table 中的列,这只会使它再次成为 INNER JOIN。
这是一种修复方法。
SELECT
.....
FROM
CalendarTemp c
LEFT JOIN SF_Extracted_Opps o
ON o.Start_Date <= c.Date AND o.End_Date >= c.Date
AND o.Start_Date <= @todate AND End_Date >= @fromdate
AND o.Office IN (@Location)
AND o.recordtypeid IN ('LAS1')
您可能 运行 遇到的另一个问题是因为您从 CalendarTemp Table 中删除了周末 Table 并非所有日期都显示了 我会测试周末是否仍然存在,看看是否有所不同结果。
这一行:
AND o.Start_Date <= @todate AND End_Date >= @fromdate
也不需要,因为您已经限制了前一行的日期和 CalendarTempTable
中的值关于您的 CalendarDate 的注释 table 您不必返回并删除这些记录,只需将星期几添加为 select 上的 WHERE 语句即可填充 table.
编辑所有办公室,您可以使用您的办公室 table 与您的 CalendarTemp table 的交叉连接来执行此操作,在您的最终查询中执行此操作,而不是在构建日历的 cte 中执行此操作。在 CTE 日历定义中这样做的问题在于它是递归的,因此您必须在锚点和递归成员定义中都这样做。
SELECT
.....
FROM
CalendarTemp c
CROSS JOIN Opportunity_offices oo
LEFT JOIN SF_Extracted_Opps o
ON o.Start_Date <= c.Date AND o.End_Date >= c.Date
AND o.Start_Date <= @todate AND End_Date >= @fromdate
AND oo.office = o.Office
AND o.recordtypeid IN ('LAS1')