Sql BQ:从多个列中选择最新日期

Sql BQ:从多个列中选择最新日期,sql,google-bigquery,Sql,Google Bigquery,大家好。早些时候我写了一个与此相关的问题,但现在我遇到了另一个问题 我必须计算install\u time和contributer\u time列之间的时间戳差异。但是,我有三个contributor_time列,我需要首先从这些列中选择最新时间,然后从安装时间中减去它 样本数据 使用者 安装时间 投稿人时间1 投稿人时间2 投稿人时间3 1. 8:00 7:45 7:50 7:55 2. 10:00 9:15 9:45 9:30 3. 11:00 10:30 无效的 无效的 您可以使用gree

大家好。早些时候我写了一个与此相关的问题,但现在我遇到了另一个问题

我必须计算install\u time和contributer\u time列之间的时间戳差异。但是,我有三个contributor_time列,我需要首先从这些列中选择最新时间,然后从安装时间中减去它

样本数据

使用者 安装时间 投稿人时间1 投稿人时间2 投稿人时间3 1. 8:00 7:45 7:50 7:55 2. 10:00 9:15 9:45 9:30 3. 11:00 10:30 无效的 无效的 您可以使用
greest()

注意:这假设值永远不会为
NULL
,根据您的示例数据,这似乎是合理的。

您可以使用
grest()

注意:这假设值永远不为空,根据您的示例数据,这似乎是合理的。

请考虑以下内容

select users, install_time,
  time_diff(
    parse_time('%H:%M',install_time), 
    greatest(
      parse_time('%H:%M',contributor_time_1), 
      parse_time('%H:%M',contributor_time_2),
      parse_time('%H:%M',contributor_time_3)
    ), 
    minute) as time_diff_min
from `project.dataset.table`    
如果应用于问题中的样本数据,则输出为

上面的可以稍微重构为下面的

create temp function latest_time(arr any type) as ((
  select parse_time('%H:%M',val) time
  from unnest(arr) val
  order by time desc
  limit 1 
));
select users, install_time,
  time_diff(
    parse_time('%H:%M',install_time), 
    latest_time([contributor_time_1, contributor_time_2, contributor_time_3]), 
    minute) as time_diff_min
from `project.dataset.table`
更少的冗长,没有冗余的解析-结果相同-所以只需考虑偏好问题

select users, install_time,
  time_diff(
    parse_time('%H:%M',install_time), 
    greatest(
      parse_time('%H:%M',contributor_time_1), 
      parse_time('%H:%M',contributor_time_2),
      parse_time('%H:%M',contributor_time_3)
    ), 
    minute) as time_diff_min
from `project.dataset.table`    
如果应用于问题中的样本数据,则输出为

上面的可以稍微重构为下面的

create temp function latest_time(arr any type) as ((
  select parse_time('%H:%M',val) time
  from unnest(arr) val
  order by time desc
  limit 1 
));
select users, install_time,
  time_diff(
    parse_time('%H:%M',install_time), 
    latest_time([contributor_time_1, contributor_time_2, contributor_time_3]), 
    minute) as time_diff_min
from `project.dataset.table`

不那么冗长,也没有冗余的解析——结果是一样的——所以只是偏好问题

Hi Gordon。谢谢你的回复。我收到了这个错误:参数类型:TIMESTAMP、STRING、DATE\u TIME\u PART的函数TIMESTAMP\u DIFF没有匹配的签名。支持的签名:TIMESTAMP_DIFF(TIMESTAMP,TIMESTAMP,DATE_TIME_部分)它看起来像是以字符串格式提供的_TIME列,需要先强制转换。我将该cast()放在查询中,但仍然收到相同的错误。你知道为什么吗?谢谢你的专业知识!(1) 你的问题和答案是关于时间而不是时间戳的。(2) 如果将值存储为字符串,则需要将其转换为适当的格式。谢谢。我应该在示例表中提供更多细节。事实上,在我检查之前,我没有意识到有空值。很高兴知道最伟大的()不能和他们一起工作。嗨,戈登。谢谢你的帮助。我不得不做一些调整,但我能够处理空字符串。我使用了最大值(cast(替换(contributor_time_1,'null',“2020-01-01 06:00:00 UTC”)作为时间戳),结果很好。谢谢你的帮助。嗨,戈登。谢谢你的回复。我收到了这个错误:参数类型:TIMESTAMP、STRING、DATE\u TIME\u PART的函数TIMESTAMP\u DIFF没有匹配的签名。支持的签名:TIMESTAMP_DIFF(TIMESTAMP,TIMESTAMP,DATE_TIME_部分)它看起来像是以字符串格式提供的_TIME列,需要先强制转换。我将该cast()放在查询中,但仍然收到相同的错误。你知道为什么吗?谢谢你的专业知识!(1) 你的问题和答案是关于时间而不是时间戳的。(2) 如果将值存储为字符串,则需要将其转换为适当的格式。谢谢。我应该在示例表中提供更多细节。事实上,在我检查之前,我没有意识到有空值。很高兴知道最伟大的()不能和他们一起工作。嗨,戈登。谢谢你的帮助。我不得不做一些调整,但我能够处理空字符串。我使用了最大值(cast(替换(contributor_time_1,'null',“2020-01-01 06:00:00 UTC”)作为时间戳),结果很好。谢谢你的帮助。你试过了吗?如果你回答了问题,就考虑投票并接受吧!因此,我们将回答您的其他/下一个问题:o)嗨,米哈伊尔,我很抱歉。我仍然习惯于堆栈溢出。我将考虑这一点,以备将来参考。感谢您的建议。上述答案中的第二个/重构版本实际上涵盖了您的空场景!!!!你好,米哈伊尔。谢谢你的回复。我尝试了重构版本,但仍然收到以下错误消息:无法解析输入字符串“null”。
null
和string
null
完全不同。我给人的印象是,您的表中有空值,而不是字符串-仍然很容易解决/调整上面的问题-只需使用
safe.parse_time
而不是
parse_time
您试过了吗?如果你回答了问题,就考虑投票并接受吧!因此,我们将回答您的其他/下一个问题:o)嗨,米哈伊尔,我很抱歉。我仍然习惯于堆栈溢出。我将考虑这一点,以备将来参考。感谢您的建议。上述答案中的第二个/重构版本实际上涵盖了您的空场景!!!!你好,米哈伊尔。谢谢你的回复。我尝试了重构版本,但仍然收到以下错误消息:无法解析输入字符串“null”。
null
和string
null
完全不同。我给人的印象是,您的表中有空值,而不是字符串-仍然很容易修复/调整上面的值-只需使用
safe.parse_time
而不是
parse_time