SQL选择具有MAX非零值的记录如果存在,则选择具有零值的记录

时间:2015-07-08 17:51:57

标签: mysql

我想要做的是在我的表格的给定日期范围内为每个唯一时间戳选择一条记录。如果同一时间戳存在多个记录,我想获得最大非零记录,或者如果只返回零值记录,我只想返回其中一个零值记录。 我一直在使用“几乎”的查询是

select timestamp, MAX(value) FROM myTable WHERE *conditions*... group by [timestamp] Order By [timestamp] ASC;

显然效果很好,直到返回的记录为零和负数,在这种情况下,它返回零记录,因为它大于负记录。在这种情况下,我想要返回一个负值记录而不是零记录。如果我试图通过将where语句改为

来解决这个问题
WHERE [Value] <> 0

如果只返回零值记录,那么我什么都得不到。我的优先级是每个时间戳返回一个最大的非零值记录,但如果只存在零值记录,则只返回其中一个,如果时间戳只存在空记录,我希望返回一个空记录。

2 个答案:

答案 0 :(得分:1)

我要做的是按照你描述的方式选择最大的非零值:

SELECT timestamp, MAX(valueCol) AS maxValue
FROM myTable
WHERE valueCol <> 0
GROUP BY timestamp;

然后,您可以使用外部联接来获取所有时间戳,并使用COALESCE()函数替换未返回0的值:

SELECT m.timestamp, COALESCE(t.maxValue, 0) AS maxValue
FROM myTable m
LEFT JOIN(
   SELECT timestamp, MAX(valueCol) AS maxValue
   FROM myTable
   WHERE valueCol <> 0
   GROUP BY timestamp) t ON t.timestamp = m.timestamp;

编辑:根据您的评论和对问题的编辑,您可以通过以下方式解决问题。我写了一个查询(如上所示)来获取每个时间戳的最大非零值。我还可以编写一个查询来获取最大/最小时间戳为0的时间戳,如下所示:

SELECT id, 0 AS MaxVal
FROM myTable
GROUP BY id
HAVING MAX(valueCol) = 0 AND MIN(valueCol) = 0;

其余组的值为null。为了获得这些,我可以像前面的例子那样进行相同的外连接,但是省略了COALESCE()函数,以便空值保持原样:

SELECT DISTINCT m.id, t.maxVal
FROM myTable m
LEFT JOIN(
  SELECT id, MAX(valueCol) AS maxVal
  FROM myTable
  WHERE valueCol <> 0
  GROUP BY id
  UNION ALL
  SELECT id, 0 AS maxVal
  FROM myTable
  GROUP BY id
  HAVING MIN(valueCol) = 0 AND MAX(valueCol) = 0) t ON t.id = m.id;

我添加了DISTINCT关键字以返回唯一的id / maxValue对,因为否则将返回多行,因为id在同一个表中多次出现。

我在SQL Fiddle进行了测试,效果很好。

答案 1 :(得分:0)

尝试一下,将@ValueCol更改为1,0,null工作正常。

DECLARE @ValueCol INT 
SET @ValueCol = Null

Select CASE WHEN MAX( CASE WHEN @ValueCol IS NULL THEN 1 ELSE 0 END) = 0  THEN MAX(@ValueCol) END

这样可以使你的SQL在原帖中看起来像这样。

select 
timestamp
, CASE WHEN MAX( CASE WHEN value IS NULL THEN 1 ELSE 0 END) = 0  THEN MAX(value) END
FROM myTable 
WHERE *conditions*... 
group by [timestamp] 
Order By [timestamp] ASC;