如何为开始日期和结束日期之间的每个工作日创建多行
How to create multiple rows for every workingday between an start and end date
我想为我的开始日期和结束日期之间的每个工作日创建一行。这样生产量就会按实际周数分配,而不仅仅是开始周数。
我现在拥有的:
SELECT DISTINCT
PH.ProdHeaderOrdNr,
PH.ProdstatusCode,
PH.partcode,
PH.description,
PBOM.subpartcode,
PBOM.description as N'Description subpart',
PBOO.qty,
PBOO.producedqty,
PBOO.machcycletime,
PBOO.qty-PBOO.producedqty as N'to produce',
case when(PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))<=0
then 0
else (PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))
end as N'amount subpart needed',
(DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1)
-(DATEDIFF(wk, PBOO.startdate, PBOO.enddate) * 2)
-(CASE WHEN DATENAME(dw, PBOO.startdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, PBOO.enddate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays,
case when PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600<=0
then 0
else Round(PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600,2)
end as N'hours remaining',
PBOO.startdate,
PBOO.enddate,
datepart(year,PBOO.startdate) as N'Year',
datepart(isoww,PBOO.startdate) as N'Week'
FROM
dbo.T_ProductionHeader AS PH,
dbo.T_ProdBillofMat as PBOM,
dbo.T_Part as P,
dbo.T_ProdBillOfOper as PBOO,
dbo.T_MachGrp as M
Where
PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode AND
PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode AND
PBOO.MachGrpCode = M.MachGrpCode AND
M.DeptCode = '0720' and
PH.ProdStatusCode BETWEEN 30 and 40 AND
PBOM.LineNr = '10' and
left(PH.partcode,1) in ('P', 'H')and
PBOO.finishedInd = 0
导致:
我想得到下一个结果:
n 行数,其中 N 等于从开始日期到结束日期的工作日数
以及以下列的值分布在这些工作日
- "to produce"
- "amount subpart needed"
- “剩余小时数”
已添加列
- "running date"(工作日日期)
- "running year"(运行 日期的年份)
- "running week"(运行 日期的等周)
我删除了 "NoOfWeekDays" 列
我已尝试创建 CTE,但无法正常工作。
根据 KumarHarsh 的回答:
我得到以下结果:
result based on KumarHarsh
这是我当前的 sql-代码:
With CTE As
(
Select PH.ProdHeaderOrdNr,
PH.ProdstatusCode,
PH.partcode,
PH.description,
PBOM.subpartcode,
PBOM.description as N'DescriptionSubpart',
PBOO.qty,
PBOO.producedqty,
PBOO.machcycletime,
PBOO.qty-PBOO.producedqty as N'ToProduce',
case when(PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))<=0
then 0
else (PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))
end as N'AmountSubpartNeeded',
(DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1)
-(DATEDIFF(wk, PBOO.startdate, PBOO.enddate) * 2)
-(CASE WHEN DATENAME(dw, PBOO.startdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, PBOO.enddate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays,
case when PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600<=0
then 0
else Round(PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600,2)
end as N'HoursRemaining',
PBOO.startdate as N'Startdate',
PBOO.enddate as N'Enddate',
datepart(year,PBOO.startdate) as N'Year',
datepart(isoww,PBOO.startdate) as N'Week'
From
dbo.T_ProductionHeader AS PH,
dbo.T_ProdBillofMat as PBOM,
dbo.T_Part as P,
dbo.T_ProdBillOfOper as PBOO,
dbo.T_MachGrp as M
where
PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode AND
PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode AND
PBOO.MachGrpCode = M.MachGrpCode AND
M.DeptCode = '0720' and
PH.ProdStatusCode BETWEEN 30 and 40 AND
PBOM.LineNr = '10' and
left(PH.partcode,1) in ('P', 'H')and
PBOO.finishedInd = 0
)
Select c.*
,ca.RunningDates,
c.toproduce/c.NoOfWeekDays as N'ProductionPerWorkDay',
c.amountsubpartneeded/c.NoOfWeekDays as N'AmountSubPartNeededPerWorkDay',
c.HoursRemaining/c.NoOfWeekDays as N'HoursRemainingPerWorkDay'
from
CTE C
cross apply(select cd.yeardate as RunningDates from dbo.T_DayOfYear CD where cd.yeardate>=c.Startdate and cd.yeardate<=c.enddate)ca
感谢 KumarHarsch 的最终工作代码。
with CTE As
(
Select PH.ProdHeaderOrdNr,
PH.ProdstatusCode,
PH.partcode,
PH.description as N'Omschrijving',
PBOM.subpartcode,
left(p.partgrpcode,1)as N'artikelgroeptype',
PBOM.description as N'Draad',
PBOO.qty,
PBOO.producedqty,
PBOO.machcycletime,
PBOO.MachGrpCode,
pbom.waste,
PBOO.qty-PBOO.producedqty as N'ToProduce',
(DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1)
-(DATEDIFF(wk, PBOO.startdate, PBOO.enddate) * 2)
-(CASE WHEN DATENAME(dw, PBOO.startdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, PBOO.enddate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays,
PBOO.startdate as N'Startdate',
PBOO.enddate as N'Enddate'
From
((dbo.T_ProductionHeader AS PH
inner join dbo.T_ProdBillofMat as PBOM on PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode)
inner join dbo.T_ProdBillOfOper as PBOO on PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode),
dbo.T_MachGrp as M,
dbo.T_part as P
where
PBOO.MachGrpCode = M.MachGrpCode AND
M.DeptCode = '0720' and
PH.ProdStatusCode in ( 11, 30, 40 ) AND
PBOM.LineNr = '10' and
left(PH.partcode,1) in ('P', 'H')and
PBOO.finishedInd = 0 and
p.partcode = pbom.subpartcode
)
Select c.*
,ca.RunningDates,
cf.ndagen,
datepart(year,ca.RunningDates) as N'Year_Run',
datepart(isoww,ca.RunningDates) as N'Week_Run',
case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end
As ProductionPerWorkDay,
case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end *(1+(convert(decimal(4,2),c.waste)/100))
as subpartneededperworkday,
case when c.machcycletime *((case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end)/c.qty)/3600<=0
then 0
else Round(c.machcycletime *((case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end)/c.qty)/3600,2)
end as N'HoursRemaining'
from
CTE C
cross apply(select cd.capacityavailabledate as RunningDates from dbo.T_machgrpRealCapacity CD where cd.MachGrpCode = c.MachGrpCode and cd.capacityavailabledate>=c.Startdate and cd.capacityavailabledate<=c.enddate and DATENAME(dw, cd.capacityavailabledate) <> 'Sunday' and DATENAME(dw, cd.capacityavailabledate) <> 'Saturday' )ca
cross apply(select count(*) as ndagen from dbo.T_machgrpRealCapacity CD where cd.MachGrpCode = c.MachGrpCode and cd.capacityavailabledate>=c.Startdate and cd.capacityavailabledate<=c.enddate and DATENAME(dw, cd.capacityavailabledate) <> 'Sunday' and DATENAME(dw, cd.capacityavailabledate) <> 'Saturday' )cf
首先创建日历Table。
以任何你想要的方式填充。
create table CalendarDate(Dates DateTime primary key)
insert into CalendarDate WITH (TABLOCK) (Dates)
select top (1000000)
DATEADD(day, ROW_NUMBER()over(order by (select null))-1,'1970-01-01') DT
from sys.objects
假设您的主要查询在 CTE 中(此脚本未经测试)
With CTE As
(
Select ,
DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1 as Diff
From
)
Select c.*
,ca.RunningDates
'to produce'/Datediff
'amount subpart needed'/Datediff
from
CTE C
cross apply(select Dates as RunningDates from CalendarDate CD where cd.dates>=c.Startdate and cd.dates<=c.enddate)ca
这个答案很重要part.if这是正确的然后你可以继续。
我希望我的改变很清楚。
像'to produce'这样的别名是错误的,应该是一个单词ToProduce。
编辑 1,
create table #temp (startdt datetime,enddate datetime)
insert into #temp values('2010-01-01','2010-01-05')
,('2011-02-01','2011-02-06')
select t.*,ca.RunningDate from #temp t
cross apply(select cd.Dates as RunningDate
from CalendarDate cd
where cd.Dates>=t.startdt and cd.Dates<=t.enddate)ca
select t.*,cd.Dates as RunningDate from #temp t
inner join CalendarDate cd
on cd.Dates>=t.startdt and cd.Dates<=t.enddate
drop table #temp
检查你自己,它按预期工作正常。
Cross apply however results in only the first row being showed
endlesly with the same value for runningdate
不是因为CROSS APPLY.Reason一定是什么东西else.Debug找到了。 you.Once 注释 CROSS APPLY 部分并检查结果或验证值 Calendar Table.
dbo.T_ProductionHeader AS PH, dbo.T_ProdBillofMat as PBOM,
不好的做法。明确提及 JOIN 语法。意外笛卡尔积连接的风险较小。逗号连接在最后 century.It 也便于其他人理解。
dbo.T_ProductionHeader AS PH inner join
dbo.T_ProdBillofMat as PBOM on PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode AND
PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode AND
将额外的过滤器放在 where 子句上,例如,PH.ProdStatusCode BETWEEN 30 and 40
。
我想为我的开始日期和结束日期之间的每个工作日创建一行。这样生产量就会按实际周数分配,而不仅仅是开始周数。
我现在拥有的:
SELECT DISTINCT
PH.ProdHeaderOrdNr,
PH.ProdstatusCode,
PH.partcode,
PH.description,
PBOM.subpartcode,
PBOM.description as N'Description subpart',
PBOO.qty,
PBOO.producedqty,
PBOO.machcycletime,
PBOO.qty-PBOO.producedqty as N'to produce',
case when(PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))<=0
then 0
else (PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))
end as N'amount subpart needed',
(DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1)
-(DATEDIFF(wk, PBOO.startdate, PBOO.enddate) * 2)
-(CASE WHEN DATENAME(dw, PBOO.startdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, PBOO.enddate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays,
case when PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600<=0
then 0
else Round(PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600,2)
end as N'hours remaining',
PBOO.startdate,
PBOO.enddate,
datepart(year,PBOO.startdate) as N'Year',
datepart(isoww,PBOO.startdate) as N'Week'
FROM
dbo.T_ProductionHeader AS PH,
dbo.T_ProdBillofMat as PBOM,
dbo.T_Part as P,
dbo.T_ProdBillOfOper as PBOO,
dbo.T_MachGrp as M
Where
PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode AND
PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode AND
PBOO.MachGrpCode = M.MachGrpCode AND
M.DeptCode = '0720' and
PH.ProdStatusCode BETWEEN 30 and 40 AND
PBOM.LineNr = '10' and
left(PH.partcode,1) in ('P', 'H')and
PBOO.finishedInd = 0
导致:
我想得到下一个结果:
n 行数,其中 N 等于从开始日期到结束日期的工作日数 以及以下列的值分布在这些工作日
- "to produce"
- "amount subpart needed"
- “剩余小时数”
已添加列
- "running date"(工作日日期)
- "running year"(运行 日期的年份)
- "running week"(运行 日期的等周)
我删除了 "NoOfWeekDays" 列
我已尝试创建 CTE,但无法正常工作。
根据 KumarHarsh 的回答:
我得到以下结果: result based on KumarHarsh
这是我当前的 sql-代码:
With CTE As
(
Select PH.ProdHeaderOrdNr,
PH.ProdstatusCode,
PH.partcode,
PH.description,
PBOM.subpartcode,
PBOM.description as N'DescriptionSubpart',
PBOO.qty,
PBOO.producedqty,
PBOO.machcycletime,
PBOO.qty-PBOO.producedqty as N'ToProduce',
case when(PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))<=0
then 0
else (PBOO.qty-PBOO.producedqty)*(1+(convert(decimal(4,2),PBOM.waste)/100))
end as N'AmountSubpartNeeded',
(DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1)
-(DATEDIFF(wk, PBOO.startdate, PBOO.enddate) * 2)
-(CASE WHEN DATENAME(dw, PBOO.startdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, PBOO.enddate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays,
case when PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600<=0
then 0
else Round(PBOO.machcycletime *((PBOO.qty-PBOO.producedqty)/PBOO.qty)/3600,2)
end as N'HoursRemaining',
PBOO.startdate as N'Startdate',
PBOO.enddate as N'Enddate',
datepart(year,PBOO.startdate) as N'Year',
datepart(isoww,PBOO.startdate) as N'Week'
From
dbo.T_ProductionHeader AS PH,
dbo.T_ProdBillofMat as PBOM,
dbo.T_Part as P,
dbo.T_ProdBillOfOper as PBOO,
dbo.T_MachGrp as M
where
PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode AND
PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode AND
PBOO.MachGrpCode = M.MachGrpCode AND
M.DeptCode = '0720' and
PH.ProdStatusCode BETWEEN 30 and 40 AND
PBOM.LineNr = '10' and
left(PH.partcode,1) in ('P', 'H')and
PBOO.finishedInd = 0
)
Select c.*
,ca.RunningDates,
c.toproduce/c.NoOfWeekDays as N'ProductionPerWorkDay',
c.amountsubpartneeded/c.NoOfWeekDays as N'AmountSubPartNeededPerWorkDay',
c.HoursRemaining/c.NoOfWeekDays as N'HoursRemainingPerWorkDay'
from
CTE C
cross apply(select cd.yeardate as RunningDates from dbo.T_DayOfYear CD where cd.yeardate>=c.Startdate and cd.yeardate<=c.enddate)ca
感谢 KumarHarsch 的最终工作代码。
with CTE As
(
Select PH.ProdHeaderOrdNr,
PH.ProdstatusCode,
PH.partcode,
PH.description as N'Omschrijving',
PBOM.subpartcode,
left(p.partgrpcode,1)as N'artikelgroeptype',
PBOM.description as N'Draad',
PBOO.qty,
PBOO.producedqty,
PBOO.machcycletime,
PBOO.MachGrpCode,
pbom.waste,
PBOO.qty-PBOO.producedqty as N'ToProduce',
(DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1)
-(DATEDIFF(wk, PBOO.startdate, PBOO.enddate) * 2)
-(CASE WHEN DATENAME(dw, PBOO.startdate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, PBOO.enddate) = 'Saturday' THEN 1 ELSE 0 END)
As NoOfWeekDays,
PBOO.startdate as N'Startdate',
PBOO.enddate as N'Enddate'
From
((dbo.T_ProductionHeader AS PH
inner join dbo.T_ProdBillofMat as PBOM on PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode)
inner join dbo.T_ProdBillOfOper as PBOO on PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode),
dbo.T_MachGrp as M,
dbo.T_part as P
where
PBOO.MachGrpCode = M.MachGrpCode AND
M.DeptCode = '0720' and
PH.ProdStatusCode in ( 11, 30, 40 ) AND
PBOM.LineNr = '10' and
left(PH.partcode,1) in ('P', 'H')and
PBOO.finishedInd = 0 and
p.partcode = pbom.subpartcode
)
Select c.*
,ca.RunningDates,
cf.ndagen,
datepart(year,ca.RunningDates) as N'Year_Run',
datepart(isoww,ca.RunningDates) as N'Week_Run',
case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end
As ProductionPerWorkDay,
case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end *(1+(convert(decimal(4,2),c.waste)/100))
as subpartneededperworkday,
case when c.machcycletime *((case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end)/c.qty)/3600<=0
then 0
else Round(c.machcycletime *((case when c.producedqty>convert(decimal(6,2),((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2))) * (c.qty/cf.ndagen) then 0
else (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)) * (c.qty/cf.ndagen)) - (((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen)) - (case when c.producedqty>((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen) then (c.producedqty-(((DATEDIFF(dd, c.startdate, ca.RunningDates) + 1)
-(DATEDIFF(wk, c.startdate, ca.RunningDates) * 2)-1) * (c.qty/cf.ndagen))) else 0 end) end)/c.qty)/3600,2)
end as N'HoursRemaining'
from
CTE C
cross apply(select cd.capacityavailabledate as RunningDates from dbo.T_machgrpRealCapacity CD where cd.MachGrpCode = c.MachGrpCode and cd.capacityavailabledate>=c.Startdate and cd.capacityavailabledate<=c.enddate and DATENAME(dw, cd.capacityavailabledate) <> 'Sunday' and DATENAME(dw, cd.capacityavailabledate) <> 'Saturday' )ca
cross apply(select count(*) as ndagen from dbo.T_machgrpRealCapacity CD where cd.MachGrpCode = c.MachGrpCode and cd.capacityavailabledate>=c.Startdate and cd.capacityavailabledate<=c.enddate and DATENAME(dw, cd.capacityavailabledate) <> 'Sunday' and DATENAME(dw, cd.capacityavailabledate) <> 'Saturday' )cf
首先创建日历Table。
以任何你想要的方式填充。
create table CalendarDate(Dates DateTime primary key)
insert into CalendarDate WITH (TABLOCK) (Dates)
select top (1000000)
DATEADD(day, ROW_NUMBER()over(order by (select null))-1,'1970-01-01') DT
from sys.objects
假设您的主要查询在 CTE 中(此脚本未经测试)
With CTE As
(
Select ,
DATEDIFF(dd, PBOO.startdate, PBOO.enddate) + 1 as Diff
From
)
Select c.*
,ca.RunningDates
'to produce'/Datediff
'amount subpart needed'/Datediff
from
CTE C
cross apply(select Dates as RunningDates from CalendarDate CD where cd.dates>=c.Startdate and cd.dates<=c.enddate)ca
这个答案很重要part.if这是正确的然后你可以继续。
我希望我的改变很清楚。
像'to produce'这样的别名是错误的,应该是一个单词ToProduce。
编辑 1,
create table #temp (startdt datetime,enddate datetime)
insert into #temp values('2010-01-01','2010-01-05')
,('2011-02-01','2011-02-06')
select t.*,ca.RunningDate from #temp t
cross apply(select cd.Dates as RunningDate
from CalendarDate cd
where cd.Dates>=t.startdt and cd.Dates<=t.enddate)ca
select t.*,cd.Dates as RunningDate from #temp t
inner join CalendarDate cd
on cd.Dates>=t.startdt and cd.Dates<=t.enddate
drop table #temp
检查你自己,它按预期工作正常。
Cross apply however results in only the first row being showed endlesly with the same value for runningdate
不是因为CROSS APPLY.Reason一定是什么东西else.Debug找到了。 you.Once 注释 CROSS APPLY 部分并检查结果或验证值 Calendar Table.
dbo.T_ProductionHeader AS PH, dbo.T_ProdBillofMat as PBOM,
不好的做法。明确提及 JOIN 语法。意外笛卡尔积连接的风险较小。逗号连接在最后 century.It 也便于其他人理解。
dbo.T_ProductionHeader AS PH inner join
dbo.T_ProdBillofMat as PBOM on PH.ProdHeaderDossierCode = PBOM.ProdHeaderDossierCode AND
PH.ProdHeaderDossierCode = PBOO.ProdHeaderDossierCode AND
将额外的过滤器放在 where 子句上,例如,PH.ProdStatusCode BETWEEN 30 and 40
。