简体   繁体   中英

How to get the average of a DATEDIFF()?

I have the following query:

SELECT 
    DATEDIFF(day, DateUsed, DateExpires) AS DaysBetweenExpirationAndUse
FROM tblOffer

How could i get the average number of days from the DaysBetweenExpirationAndUse column?

This should work fine:

SELECT AVG(DATEDIFF(d, DateUsed, DateExpires)) AS AvgDaysBetweenExpirationAndUse 
FROM tbl

If you want decimal places in your AVG:

SELECT AVG(DATEDIFF(d, DateUsed, DateExpires)*1.0) AS AvgDaysBetweenExpirationAndUse 
FROM tbl

If you want to select the AVG and other fields too, without grouping:

SELECT *
      ,AVG(DATEDIFF(d, DateUsed, DateExpires)*1.0) OVER() AS AvgDaysBetweenExpirationAndUse 
FROM tbl

this sql could execute?

SELECT AVG(t.a) from
  (
    SELECT DATEDIFF(d, DateUsed, DateExpires) AS a 
    FROM tbl
  ) as t

this is my test:

在此处输入图片说明

but good answer is:

SELECT AVG(DATEDIFF(d, DateOne, DateTwo)*1.0) AS avgDate
    FROM Test
SELECT AVG(DATEDIFF(d, DateUsed, DateExpires)) FROM tbl

should work fine. Note, that since DATEDIFF returns an integer value, the result also will be an integer.

If you want the "exact" (as far as floating point gets) average, use

SELECT AVG(CAST(DATEDIFF(d, DateUsed, DateExpires) AS FLOAT)) FORM tbl

DATEDIFF function has nothing to do with this problem of calculating the average(AVG) of INT values. The behavior of SQL Server is different than others servers but is according to ANSI SQL standard

If AVG is specified and DT is exact numeric (personal note: INT is an exact numeric), then the data type of the result is exact numeric with implementation- defined precision not less than the precision of DT and implementation-defined scale not less than the scale of DT.

which is (in my opinion) not to helpful in this case. Most of people will expect that AVG(INT value) will result in a NUMERIC/DECIMAL/FLOAT/REAL result but the result will be a truncated INT value. The solution is to convert [TINY|SMALL|BIT]INT values to DECIMAL/NUMERIC using CONVERT(DECIMAL(p,s)/NUMERIC(p,s), ...) or by simply multiply with 1. or 1.0 .

Example:

SELECT  ColINT, SQL_VARIANT_PROPERTY(ColINT,'BaseType') AS Col_DataType
FROM
(
    SELECT 10 AS ColINT UNION ALL SELECT 9 
) x;
/*
ColINT      Col_DataType
----------- ------------
10          int
9           int
*/

SELECT  AVG(ColINT) AS Avg#1, SQL_VARIANT_PROPERTY(AVG(ColINT),'BaseType') AS Avg#1_DataType
FROM
(
    SELECT 10 AS ColINT UNION ALL SELECT 9 
) x;
/*
Avg#1       Avg#1_DataType
----------- --------------
9           int
*/

SELECT  AVG(ColINT) AS Avg#2, SQL_VARIANT_PROPERTY(AVG(ColINT),'BaseType') AS Avg#2_DataType
FROM
(
    SELECT 10 AS ColINT UNION ALL SELECT 9
) x;
/*
Avg#2       Avg#2_DataType
----------- --------------
9           int
*/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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