【问题标题】:Select only rows with max date仅选择具有最大日期的行
【发布时间】:2019-01-23 12:19:47
【问题描述】:

在 clickhouse 表中,一个_id 有多行。我想要的是每个_id 只获得一行,其中_status_set_at 列具有其最大值。 这就是我目前所处的位置:

SELECT _id, max(_status_set_at), count(_id)
FROM pikta.candidates_states
GROUP BY _id

因为我不能在WHERE 子句中使用max() 函数,如何解决这个问题? count(_id) 显示每个 _id 有多少行,如果查询正确,它应该显示 1。 另外,据我所知,Clickhouse 数据库中没有ON 子句。

UPD:Clickhouse 中有 ON 子句

【问题讨论】:

    标签: sql database clickhouse


    【解决方案1】:

    您的查询返回您需要的内容 - 每个 _id 只有一行,其中 _status_set_at 列具有最大值。 您无需更改原始查询中的任何内容。

    count(_id) 显示原始表中每个 _id 的行数,而不是查询结果中的行数。 查询结果每个_id只有一行,因为你是按_id分组的。

    这个查询表明在你的查询结果中每个_id只有一行

    SELECT _id, max_status_set_at, count(_id) FROM (
    SELECT _id, max(_status_set_at) max_status_set_at
    FROM pikta.candidates_states
    GROUP BY _id) t
    GROUP BY _id
    

    如果您需要在 max(_status_set_at) 上应用条件,您可以使用 HAVING

    【讨论】:

      【解决方案2】:

      解决方案 - 1:

      SELECT Z._id,
             Z._status_set_at
        FROM 
      (
      SELECT _id, 
             _status_set_at, 
             max(_status_set_at) OVER ( PARTITION BY _id ORDER BY _status_set_at DESC ) AS rnk
      FROM pikta.candidates_states
      ) Z
      WHERE Z.rnk = 1;
      

      解决方案 - 2:

      SELECT A._id,
             A._status_set_at  
        FROM pikta.candidates_states A
      CROSS JOIN
             ( 
               SELECT _id, 
                      MAX(_status_set_at) AS max_status_set_dt         
                 FROM pikta.candidates_states
               GROUP BY _id
              ) B
      WHERE A._id = B._id
        AND A._status_set_at = B.max_status_set_dt; 
      

      【讨论】:

      • 我猜,Clickhouse中也没有实现分区和over
      • 他说 > Clickhouse 数据库中没有 ON 子句
      • @Teja 没有。只有 ALL/ANY OUTER/INNER JOIN
      • 第二种解决方案非常接近我想要的,但有些 _id 仍然获得多个值。 imgur.com/a/Ofm6rGq
      • 交叉联接是否返回任何结果或抛出错误?
      【解决方案3】:

      如果你想要你在 where 语句上的 max 子句,也许这会起作用

      SELECT * from (SELECT _id, max(_status_set_at) as [MaxDate], count(_id) as [RepeatCount]
          FROM pikta.candidates_states
          GROUP BY _id) t WHERE t.MaxDate = '@parameter'
      

      【讨论】:

        【解决方案4】:

        <other columns> 替换为您需要选择的其他列的列表。

        SELECT _id, _status_set_at, <other columns>
        FROM pikta.candidates_states
        WHERE (_id, _status_set_at) in (
            SELECT _id, max(_status_set_at)
            FROM pikta.candidates_states
            GROUP BY _id
        )
        

        内部选择返回一对_id,最大_status_set_at对应_id。外部选择从表中返回带有附加列的行,但仅返回其中_id_status_set_at 是内部选择结果的行,即每个_id 的最大_status_set_at

        我发布了我的回复,因为据我所知,以前的答案都不适用于最初的问题。有问题的请求应该能够返回其他列,不仅是_id_status_set_at,否则没用,你可以使用基本的选择,这已经在问题中提到了。迈克的回答不能这样修改。 Teja 的解决方案在 Clickhouse 中不起作用。

        【讨论】:

          【解决方案5】:

          在clickhouse中,这会起作用

          select _id, argMax(<col you need>, _status_set_at) from pikta.candidates_states group by _id;
          

          argMax

          【讨论】:

            猜你喜欢
            • 2015-05-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多