简体   繁体   English

SQL - AVG 输出不正确

[英]SQL - AVG Output is incorrect

In below query, I am calculating the lead time between two different dates and eventually trying to get the average of that lead time but the output is incorrect.在下面的查询中,我正在计算两个不同日期之间的提前期,并最终试图获得该提前期的平均值,但输出不正确。

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

To troubleshoot the above query I extract the data by using the same query below and when I manually calculate the lead time and average it was correct.为了对上述查询进行故障排除,我使用下面的相同查询提取数据,当我手动计算提前期和平均值时,它是正确的。 Don't know where is the issue?不知道问题出在哪里? can someone please tell me whether anything wrong with my query.有人可以告诉我我的查询是否有问题。 Please click on the link to refer sample data Link请点击链接参考样本数据链接

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

ok, now I understand.. I think you have to group by orders before to calculate avg好的,现在我明白了..我认为你必须先按订单分组才能计算平均值

;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

I will try to convert your dates to DATE instesad of DATETIME I think you are filtering too much rows because '20170831' is '2017-08-31 00:00:00' and you are loosing all ORDERDATE between '00:00:00' and '23:59:59' (for '2017-08-31')我会尝试将您的日期转换为DATE instesad of DATETIME我认为您过滤了太多行,因为 '20170831' 是 '2017-08-31 00:00:00' 并且您正在丢失 '00:00:00 之间的所有ORDERDATE ' 和 '23:59:59'(对于 '2017-08-31')

WHERE   ORDERTYPE <> 'Exchange Order' 
AND CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831' 
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL

With the help of MtwStark i was able to resolve this.在 MtwStark 的帮助下,我能够解决这个问题。 I have modified his query, Thanks buddy我已经修改了他的查询,谢谢哥们

;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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM