【问题标题】:SQL: need only 1 row per particular timestampSQL:每个特定时间戳只需要 1 行
【发布时间】:2011-03-21 14:27:00
【问题描述】:

我有一些 SQL 代码从另一个(非基于 sql 的)系统插入值。我得到的值之一是时间戳。

我可以获得具有相同时间戳的多个插入(尽管其他字段的值不同)。

我的问题是我试图让自特定日期以来每天发生的第一个插入(基于时间戳)(即给我自 2007 年 1 月 28 日以来每天的第一个插入...)

我获取每天第一个时间戳的代码如下:

SELECT MIN(my_timestamp) AS first_timestamp
FROM my_schema.my_table
WHERE my_col1 = 'WHATEVER'
AND my_timestamp > timestamp '2010-Jul-27 07:45:24' - INTERVAL '365 DAY'
GROUP BY DATE (my_timestamp);

这为我提供了可用时间列表。但是当我加入反对这些时间时,我可以获得几行,因为有很多行与这些时间相匹配。因此,在 365 天内,我可能会得到 5,000 行(我可以在每天 00:00:00 插入 100 行)。

假设在上面的示例中,my_table 有列 my_col1 和 my_col2,我怎样才能获得包含 my_col1 和 my_col2 的准确 365 行?如果一个日期有多行,我返回哪一行并不重要;任何行就足够了。

这是一个奇怪的问题。总体问题是:给定一个时间戳,即使有多行已经说过时间戳(假设没有其他优先级),如何才能获得 1-row-per-timestamp?

提前感谢您的帮助。

编辑: 例如,假设此表具有以下列:my_col1、my_col2 和 my_timestamp。
以下是示例值(按 my_col1 - my_col2 - my_timestamp 的顺序):

  • 'my_val1' - 10 - '2010-07-01 01:01:01'
  • 'my_val2' - 11 - '2010-07-01 01:01:01'
  • 'my_val3' - 12 - '2010-07-01 01:01:01'
  • 'my_val4' - 13 - '2010-07-01 01:01:02'
  • 'my_val5' - 14 - '2010-07-02 01:01:01'
  • 'my_val6' - 15 - '2010-07-02 01:01:01'
  • 'my_val7' - 16 - '2010-07-03 01:01:01'

最后,我只想要 3 行,1 行带有时间戳,带有“2010-07-01 01:01:01”,一行带有“2010-07-02 01:01:01”,另一行带有'2010-07-03 01:01:01'。第三个很简单,因为最后一个时间戳只有 1 行。但前两个是棘手的。我在上面发布的 sql 将忽略带有 'my_val4' 的行。

我需要一个能返回所有列的查询,而不仅仅是日期。

我如何让 sql 给我与该时间戳匹配的第一个或最后一个值(无论哪种方式都无关紧要。我只需要获得 1 个第一天的时间戳匹配)?

【问题讨论】:

  • 我不明白你的问题。您现有的查询看起来应该为每个日期返回一行,即使每天有多行。这似乎是您所要求的。但是,您还暗示将另一个表加入到查询中。如果您要加入另一个表,则需要在问题中包含该信息。
  • mytable 有唯一的键域吗?
  • RE 标记:是的,mytable 有一个唯一的关键字段(事务 id)。 RE 迈克:我现有的查询确实在每个日期返回一行。但该查询每天只提供最早的插入。当我加入同一个表以获取表中的其余值时,我可以获得多对一的情况,其中我可能有 10 个插入都落在特定的时间戳上。我不仅需要第一次插入的日期。我还需要该行中的其他所有内容。

标签: sql postgresql join timestamp


【解决方案1】:

我知道您已经有了答案,但我仍然不明白您为什么在问题中提到了 join。为什么不在查询中包含其余列,如下所示:

SELECT MIN(my_timestamp) AS first_timestamp, my_col1, my_col2
FROM my_table
GROUP BY DATE(my_timestamp);

这适用于 MySQL。在 PostgreSQL 中它不会返回预期的结果吗?

【讨论】:

  • 没有。 Postgres 中的“GROUP BY”不能这样工作。您必须为您尝试选择的每个元素执行“分组依据”,这实际上意味着您正在尝试对所有 3 个字段进行“区分”,这不是预期的结果。感谢您的意见。
【解决方案2】:
select distinct on (date(my_timestamp)) *
from my_table
order by date(my_timestamp), my_timestamp

这会选择所有列,每个 date(my_timestamp) 恰好一行。每天的单行是该组的第一行,由order by 确定(因此这是my_timestamp 最少的行)。

当然,您可以添加任何您需要的joinswheres 等。但这是您要查找的存根。

【讨论】:

    【解决方案3】:

    解决方法是使用SQL的DISTINCT语句(http://www.sql-tutorial.com/sql-distinct-sql-tutorial/):

    SELECT DISTINCT MIN(my_timestamp) AS first_timestamp FROM my_schema.my_table WHERE my_col1 = 'WHATEVER' AND my_timestamp > timestamp '2010-Jul-27 07:45:24' - INTERVAL '365 DAY' GROUP BY DATE (my_timestamp);
    

    【讨论】:

    • 当谈到日期时,我已经得到了不同的行。在你的 sql 中,'distinct' 关键字什么都不做(冗余)。 'group by' 解决了这个问题。需要加入我上面给出的 SQL,但我不知道要加入什么才能得到我想要的。
    • 查询中的“分组依据”应该已经放弃了我不需要独特的事实(stackoverflow.com/questions/426723/sql-group-by-versus-distinct),特别是考虑到我只选择了 1 列(为什么使用独特的& 对只返回 1 列的查询进行分组?)。
    • 对不起,误解了你的问题。能否请您具体说明您要加入的表是什么样的?
    猜你喜欢
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多