【问题标题】:Filter the lowest values of a sql result every time a column changes每次列更改时过滤 sql 结果的最小值
【发布时间】:2022-01-23 17:13:51
【问题描述】:

对不起,奇怪的标题我很难解释我需要什么,但我会尽力而为,

我的表 BehaviorHidraulics 包含以下列: [id],[siteIDDatagate],[datetime],[value],[channelnum],[channeltype],现在我需要在某个日期找到 [value] 的最小值,我已经设法做到了查询:

select  min(value) as minvalue, siteIDDatagate, channeltype, channelnum, datetime 
  from BehaviorHidraulic where channelnum = '1' and datetime 
  between '2021-10-10 00:00:00' and '2021-10-10 23:59:59' 
  group by siteIDDatagate, channeltype, channelnum, datetime order by siteIDDatagate, minvalue ASC

现在返回如下内容:

minvalue  siteIDDatagate
26         _site_1003
26,39      _site_1003 
26,5       _site_1003 
17,20      _site_303
17,600     _site_303
58,200     _site_304
58,599     _site_304

这很好,但我需要在每个站点的第一行下删除每个结果,以便它看起来像这样:

minvalue  siteIDDatagate
26         _site_1003
17,20      _site_303
58,200     _site_304

我想我需要使用滞后功能,但我对 SQL 不是很好,所以非常感谢任何帮助

【问题讨论】:

  • 从 GROUP BY 表达式和输出列表中删除多余的列。
  • 从 grouü 中删除 datetime by 或将其更改为 DATE(datetime) 并将 datetime 添加到 fiellist 中,例如 select datetime ,.. your fields
  • @Akina 这不符合我的要求,它只是减少了结果中的列数。
  • 是的,但是假设“channeltype”列将例如分组三个或四个不同的值,您希望在其他列中显示什么
  • 这不符合我的要求,它只是减少了结果中的列数。 ???但是您已经接受了准确实现我的方法的答案。

标签: mysql sql database


【解决方案1】:

在这种情况下,我认为滞后功能不会对您有所帮助。 lag 函数是一个窗口函数,允许您访问前一行中的数据。 Akina,发布了我认为适合你的答案。

目前您的查询是:

select  min(value) as minvalue, siteIDDatagate, channeltype, channelnum, datetime
  from BehaviorHidraulic where channelnum = '1' and datetime 
  between '2021-10-10 00:00:00' and '2021-10-10 23:59:59' 
  group by siteIDDatagate, channeltype, channelnum, datetime order by siteIDDatagate, minvalue ASC

您拥有的其他“分组依据”字段导致行数过多。您的结果似乎只关心 min(value)siteIDDatagate 但您不必要地对其他字段进行分组。您应该考虑这样重写查询:

select  min(value) as minvalue, siteIDDatagate
  from BehaviorHidraulic where channelnum = '1' and datetime 
  between '2021-10-10 00:00:00' and '2021-10-10 23:59:59' 
  group by siteIDDatagate order by siteIDDatagate, minvalue ASC

这将确保您只在为每个siteIDDatagate 指定的日期期间检索最少的value

如需其他要求,请注明。

【讨论】:

  • 这很好用,对不起 Akina 我想我理解错了,你说的是正确的。谢谢大家
【解决方案2】:

您可以使用 row_number() 窗口函数来查找第一条记录(具有最小值的记录)。这是一个例子

;with cte AS
(
  select siteIDDatagate, 
         channeltype, 
         channelnum, 
         datetime,
         value,
         row_number() over(PARTITION BY siteIDDatagate, channeltype, channelnum ORDER BY value) AS RN
  from BehaviorHidraulic where channelnum = '1' 
       and datetime between '2021-10-10 00:00:00' and '2021-10-10 23:59:59' 
)
SELECT *
FROM cte 
WHERE RN = 1

【讨论】:

  • 每个站点返回一行,但不返回值本身
  • 您只需在 cte 的选择列表中添加“值”。查询已更新。
猜你喜欢
  • 2013-11-01
  • 1970-01-01
  • 2020-04-16
  • 2012-07-04
  • 2012-12-15
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多