在下面的查询中,我正在计算两个不同日期之间的提前期,并最终尝试获得提前期的平均值,但输出不正确。
SELECT
Round(AVG(CAST(
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, INVOUTDATE, 105)) = 'Sunday' THEN 0 ELSE 0 END) end end AS FLOAT)),4) AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
要解决上述问题,我使用下面相同的查询提取数据,当我手动计算提前期时,平均值是正确的。 不知道问题出在哪里?有人可以告诉我我的查询是否有任何问题。 请点击链接以参考样本数据https://jsfiddle.net/samollason/uvqosxrr/3/
SELECT DISTINCT DOCKETNO,
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, INVOUTDATE, 105)) = 'Sunday' THEN 0 ELSE 0 END) end end AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
答案 0 :(得分:1)
;with
S AS (
select DOCKETNO, ORDERDATE, INVOUTDATE, COUNT(*) n
from DSORDERSTATUS where ORDERTYPE <> 'Exchange Order'
group by DOCKETNO, ORDERDATE, INVOUTDATE
),
D as (
select [DOCKETNO], [ORDERDATE], [INVOUTDATE],
DATEDIFF(dd, CONVERT(date, [ORDERDATE], 105), CONVERT(date, [INVOUTDATE], 105)) dd,
DATEDIFF(wk, CONVERT(date, [ORDERDATE], 105), CONVERT(date, [INVOUTDATE], 105)) wk,
CASE WHEN DATEPART(dw, CONVERT(datetime, ORDERDATE, 105)) = 7 THEN 1 ELSE 0 END IsSundayOrd,
CASE WHEN DATEPART(dw, CONVERT(datetime, INVOUTDATE, 105)) = 7 THEN 1 ELSE 0 END IsSundayInv
from S
)
select avg(cast(dd - case when dd>1 then (wk + IsSundayOrd + IsSundayInv) else 0 end as float)) leadtime
from D
where CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL
答案 1 :(得分:0)
我会尝试将您的日期转换为DATE
instesad DATETIME
我认为您过滤了太多行,因为&#39; 20170831&#39;是&#39; 2017-08-31 00:00:00&#39;而且你在{00} 00:00:00&#39;之间失去所有ORDERDATE
和&#39; 59:59&#39; (对于&#39; 2017-08-31&#39;)
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL
答案 2 :(得分:0)
在MtwStark的帮助下,我能够解决这个问题。 我修改了他的查询, 谢谢伙伴
;with
S AS (
SELECT DISTINCT DOCKETNO,
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)end end AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170808'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
),
D AS (
SELECT DOCKETNO, LEADTIME FROM S
)
SELECT AVG(CAST(LEADTIME AS FLOAT)) FROM D