Sql server 查找Average、MaxValue和MinValue以及相应的值出现的日期时间

Sql server 查找Average、MaxValue和MinValue以及相应的值出现的日期时间,sql-server,datetime,Sql Server,Datetime,我正在处理一个SQL查询,其中我必须找出任意日期的每组的平均值、最大值、最大值DateTime、最小值、最小值DateTime。为此,我使用了以下查询 SELECT Dl.TagDescID, convert( decimal(18,2), AVG( Dl.Value ) ) AS 'TotalAvgValue', convert(decimal(18,2), MAX( Dl.Value ) ) AS 'MaxValue', MAX( Dl.Date ) MaxD

我正在处理一个SQL查询,其中我必须找出任意日期的每组的平均值、最大值、最大值DateTime、最小值、最小值DateTime。为此,我使用了以下查询

SELECT
    Dl.TagDescID,
    convert( decimal(18,2), AVG( Dl.Value ) ) AS 'TotalAvgValue',
    convert(decimal(18,2), MAX( Dl.Value ) ) AS 'MaxValue',
    MAX( Dl.Date ) MaxDate,
    convert( decimal(18,2), MIN( Dl.Value ) ) AS 'MinValue',
    Min( Dl.Date ) MinDate
FROM
    tblDataLog AS Dl WITH (nolock) 
    INNER JOIN tblTagDescription AS TD WITH (nolock) ON Dl.TagDescID = TD.ID 
WHERE
    ( CONVERT(date, Dl.Date, 103) = CONVERT(date, @StartDate, 103) )
    AND
    ( TD.GroupName = @Group )
GROUP BY
    Dl.TagDescID
`

     TagDescID  TotalAvgValue   MaxValue    MaxDate MinValue    MinDate
       1    36.59   36.59   2020-01-07 10:13:42.293 36.59   2020-01-07 10:13:32.750
       2    20.49   20.49   2020-01-07 10:13:42.293 20.49   2020-01-07 10:13:32.750

In the above Data Set The MaxValue of TagDescID 1 is 36.59 and its Date as 'MaxDate' should be the exact datetime when this maxvalue Arrives in the table tblDataLog. here Max-Date of MaxValue of TagDescID 1 is '2020-01-07 10:13:42.293' but the value should have been '2020-01-07 08:13:42.293'. Same for MinValue and MinDate For each TagDescID.

How to solve it?




我想这就是你想要的。值为最小值和最大值时的相应日期。您可以使用子查询来执行此操作

SELECT
    Dl.TagDescID,
    convert( decimal(18,2), AVG( Dl.Value ) ) AS 'TotalAvgValue',
    convert(decimal(18,2), MAX( Dl.Value ) ) AS 'MaxValue',
    --MAX( Dl.Date ) MaxDate,
    (SELECT TOP 1 x.[Date] FROM  tblDataLog x WHERE x.TagDescID = Dl.TagDescID ORDER BY Value DESC) As MaxDate,
    convert( decimal(18,2), MIN( Dl.Value ) ) AS 'MinValue',
    --Min( Dl.Date ) MinDate
    (SELECT TOP 1 x.[Date] FROM  tblDataLog x WHERE x.TagDescID = Dl.TagDescID ORDER BY Value) As MinDate
FROM
    tblDataLog AS Dl WITH (nolock) 
    INNER JOIN tblTagDescription AS TD WITH (nolock) ON Dl.TagDescID = TD.ID 
WHERE
    ( CONVERT(date, Dl.Date, 103) = CONVERT(date, @StartDate, 103) )
    AND
    ( TD.GroupName = @Group )
GROUP BY
    Dl.TagDescID
编辑:正如其他人评论的那样,避免CONVERTdate,Dl.Date,103=CONVERTdate,@StartDate,103

你可以用

WHERE Dl.Date >= @StartDate
AND   Dl.Date <  DATEADD (DAY, 1, @StartDate)

我想这就是你想要的。值为最小值和最大值时的相应日期。您可以使用子查询来执行此操作

SELECT
    Dl.TagDescID,
    convert( decimal(18,2), AVG( Dl.Value ) ) AS 'TotalAvgValue',
    convert(decimal(18,2), MAX( Dl.Value ) ) AS 'MaxValue',
    --MAX( Dl.Date ) MaxDate,
    (SELECT TOP 1 x.[Date] FROM  tblDataLog x WHERE x.TagDescID = Dl.TagDescID ORDER BY Value DESC) As MaxDate,
    convert( decimal(18,2), MIN( Dl.Value ) ) AS 'MinValue',
    --Min( Dl.Date ) MinDate
    (SELECT TOP 1 x.[Date] FROM  tblDataLog x WHERE x.TagDescID = Dl.TagDescID ORDER BY Value) As MinDate
FROM
    tblDataLog AS Dl WITH (nolock) 
    INNER JOIN tblTagDescription AS TD WITH (nolock) ON Dl.TagDescID = TD.ID 
WHERE
    ( CONVERT(date, Dl.Date, 103) = CONVERT(date, @StartDate, 103) )
    AND
    ( TD.GroupName = @Group )
GROUP BY
    Dl.TagDescID
编辑:正如其他人评论的那样,避免CONVERTdate,Dl.Date,103=CONVERTdate,@StartDate,103

你可以用

WHERE Dl.Date >= @StartDate
AND   Dl.Date <  DATEADD (DAY, 1, @StartDate)

问题在于,您实际上要求同时使用多个聚合集和分组集。您观察到的是,每个列聚合表达式都独立于其他列返回该聚合的结果,这是出于设计

在上面的查询中,MaxDate和MinDate应该是将MaxValue或MinValue插入表tblDataLog时的日期时间

在SQLServer中,我们有很多方法来查询这个问题

一种方法是查询集合中的“最大”和“最小”值,然后重新查询集合中这些时间的“最大”和“最小”日期

在本例中,我使用CTE而不是简单的嵌套查询,因为我发现语法更具可读性

对于每日CTE中的每个结果,两个交叉应用查询将评估一次。 此解决方案可以更有效地对相应日志记录的DateTime使用内联查找,因为它不必对tblDataLog中的每一行进行一次查找,此解决方案将为group by返回的每一行额外查找两次

;每日作为 选择 Dl.TagDescID, convertdecimal18,2,AVGDl.Value为[TotalAvgValue], convertdecimal18,2,MAXDl.Value为[MaxValue], convertdecimal18,2,MINDl.Value为[MinValue] 从@tblDataLog作为Dl 内部连接@tblTagDescription作为Dl.TagDescID=TD.ID上的TD 其中CONVERTdate、Dl.Date、103=CONVERTdate、@StartDate、103和TD.GroupName=@Group 按Dl.TagDescID分组 选择Daily.TagDescID、TotalAvgValue、MaxValue、[Max].Date MaxDate、MinValue、[Min].Date MinDate 每日 交叉应用从@tblDataLog DlMax中选择MAXDlMax.Date日期,其中DlMax.TagDescID=Daily.TagDescID和CONVERTdate,DlMax.Date,103=CONVERTdate,@StartDate,103和DlMax.Value=Daily.MaxValue为[Max] 交叉应用从@tblDataLog DlMin中选择MINDlMin.Date日期,其中DlMin.TagDescID=Daily.TagDescID和CONVERTdate、DlMin.Date、103=CONVERTdate、@StartDate、103和DlMin.Value=Daily.MinValue为[Min] 另一种方法是按日期分组,而不是筛选明确的日期值,因此这将按日期和标记进行汇总,如果需要,可以跨多个日期和多个标记生成报告:

;每日作为 选择 Dl.TagDescID, TD.GroupName, 转换日期,Dl.日期,103作为日期, MAXDl.Date作为Max_日期, MINDl.Date作为Min_Date, convertdecimal18,2,AVGDl.Value为[TotalAvgValue], convertdecimal18,2,MAXDl.Value为[MaxValue], convertdecimal18,2,MINDl.Value为[MinValue] 从@tblDataLog作为Dl 内部连接@tblTagDescription作为Dl.TagDescID=TD.ID上的TD 按Dl.TagDescID、TD.GroupName、CONVERTdate、Dl.Date、103分组 选择Daily.Date,Daily.GroupName,Daily.TagDescID,TotalAvgValue,MaxValue,[Max]。Date MaxDate,MinValue,[Min]。Date MinDate 每日
交叉应用从@tblDataLog DlMax中选择MAXDlMax.Date Date Date,其中DlMax.TagDescID=Daily.TagDescID和DlMax.Date>=Daily.Min_Date和DlMax.Date=Daily.Min_Date和DlMin.Date问题在于,您实际上是在同时要求多个聚合集和分组集。您观察到的是,每个列聚合表达式都独立于其他列返回该聚合的结果,这是出于设计

在上面的查询中,MaxDate和MinDate应该是将MaxValue或MinValue插入表tblDataLog时的日期时间

在SQLServer中,我们有很多方法来查询这个问题

一种方法是查询集合中的“最大”和“最小”值,然后重新查询集合中这些时间的“最大”和“最小”日期

在本例中,我使用CTE而不是简单的嵌套查询,因为我发现语法更具可读性

对于每日CTE中的每个结果,两个交叉应用查询将评估一次。 此解决方案可以更有效地对相应日志记录的DateTime使用内联查找,因为它不必对tblDataLog中的每一行进行一次查找,此解决方案将为group by返回的每一行额外查找两次。

;每日作为 选择 Dl.TagDescID, convertdecimal18,2,AVGDl.Value为[TotalAvgValue], convertdecimal18,2,MAXDl.Value为[MaxValue], convertdecimal18,2,MINDl.Value为[MinValue] 从@tblDataLog作为Dl 内部连接@tblTagDescription作为Dl.TagDescID=TD.ID上的TD 其中CONVERTdate、Dl.Date、103=CONVERTdate、@StartDate、103和TD.GroupName=@Group 按Dl.TagDescID分组 选择Daily.TagDescID、TotalAvgValue、MaxValue、[Max].Date MaxDate、MinValue、[Min].Date MinDate 每日 交叉应用从@tblDataLog DlMax中选择MAXDlMax.Date日期,其中DlMax.TagDescID=Daily.TagDescID和CONVERTdate,DlMax.Date,103=CONVERTdate,@StartDate,103和DlMax.Value=Daily.MaxValue为[Max] 交叉应用从@tblDataLog DlMin中选择MINDlMin.Date日期,其中DlMin.TagDescID=Daily.TagDescID和CONVERTdate、DlMin.Date、103=CONVERTdate、@StartDate、103和DlMin.Value=Daily.MinValue为[Min] 另一种方法是按日期分组,而不是筛选明确的日期值,因此这将按日期和标记进行汇总,如果需要,可以跨多个日期和多个标记生成报告:

;每日作为 选择 Dl.TagDescID, TD.GroupName, 转换日期,Dl.日期,103作为日期, MAXDl.Date作为Max_日期, MINDl.Date作为Min_Date, convertdecimal18,2,AVGDl.Value为[TotalAvgValue], convertdecimal18,2,MAXDl.Value为[MaxValue], convertdecimal18,2,MINDl.Value为[MinValue] 从@tblDataLog作为Dl 内部连接@tblTagDescription作为Dl.TagDescID=TD.ID上的TD 按Dl.TagDescID、TD.GroupName、CONVERTdate、Dl.Date、103分组 选择Daily.Date,Daily.GroupName,Daily.TagDescID,TotalAvgValue,MaxValue,[Max]。Date MaxDate,MinValue,[Min]。Date MinDate 每日
交叉应用从@tblDataLog DlMax中选择MAXDlMax.Date Date Date,其中DlMax.TagDescID=Daily.TagDescID和DlMax.Date>=Daily.Min_Date和DlMax.Date=Daily.Min_Date和DlMin.Date您应该包括一个摘要数据集和结果集,显示您期望的结果和实际观察到的结果,以便按日期进行筛选,同时返回MaxDate和MinDate我想我们遗漏了一些东西,如果我们按日期过滤,那么Max和Min将是相同的值。。。或者您正在寻找指定日期的最大和最小时间?我想要任何日期的每个标记的平均值、MaxValue、MaxValue DateTime、MinValue、MinValue DateTime请提供一些示例数据和预期结果-这是清楚地传达您要找的内容的唯一方法。此外,您当然应该避免与nolock一起使用,除非它是绝对必要的。您不应该使用CONVERT-date,Dl.date,103,因为它不是可搜索谓词。为什么@StartDate不是一个日期值?CREATE TABLE语句中Dl.Date的实际数据类型是什么?您应该包括一个摘要数据集和结果集,显示您期望的结果和实际观察到的结果。因此,您希望按日期进行筛选,但同时返回MaxDate和MinDate。如果按日期进行筛选,我认为我们在这里遗漏了一些内容,那么最大值和最小值将是相同的值。。。或者您正在寻找指定日期的最大和最小时间?我想要任何日期的每个标记的平均值、MaxValue、MaxValue DateTime、MinValue、MinValue DateTime请提供一些示例数据和预期结果-这是清楚地传达您要找的内容的唯一方法。此外,您当然应该避免与nolock一起使用,除非它是绝对必要的。您不应该使用CONVERT-date,Dl.date,103,因为它不是可搜索谓词。为什么@StartDate不是一个日期值?CREATETABLE语句中Dl.Date的实际数据类型是什么?上面的查询显示了错误的Max Date和Min Time。我正在搜索20年1月7日,它显示的是2020年1月3日和2020年1月6日。如果你能提供一些样本数据,那就太好了。到目前为止,我们只是猜测您的需求。上面的查询显示了错误的最大日期和最小时间。我正在搜索20年1月7日,它显示的是2020年1月3日和2020年1月6日。如果你能提供一些样本数据,那就太好了。到目前为止,我们只是猜测你的要求