迭代列中的时间戳行值并在 SQL 中执行 countif?

Posted

技术标签:

【中文标题】迭代列中的时间戳行值并在 SQL 中执行 countif?【英文标题】:Iterating over timestamp row values within a column and performing a countif in SQL? 【发布时间】:2021-01-12 00:22:54 【问题描述】:

现在我有一个名为 dates 的视图,看起来像这样:

|first_day|last_day|
|---------|--------|
|2020-08-17T00:00:00+00:00|2020-12-04T00:00:00+00:00|
|2020-11-23T00:00:00+00:00|2020-12-07T00:00:00+00:00|
|2020-09-14T00:00:00+00:00|2020-12-04T00:00:00+00:00|
|2020-09-14T00:00:00+00:00|2020-12-04T00:00:00+00:00|
|2020-09-14T00:00:00+00:00|2020-12-04T00:00:00+00:00|

... 大约 300 行...

我使用此 SQL 查询创建了另一个视图以生成从 2020 年 6 月 1 日到今天(无论那天是哪一天)的一行日期:

SELECT GENERATE_TIMESTAMP_ARRAY('2020-06-01', CURRENT_TIMESTAMP(), INTERVAL 1 DAY) AS date

生成这样的表(我们称之为dateseries):

|date|
|----|
|2020-06-01 00:00:00 UTC|
|2020-06-02 00:00:00 UTC|
|2020-06-03 00:00:00 UTC|
|2020-06-04 00:00:00 UTC|

...从 2020 年 6 月 1 日到 current_timestamp,间隔 1 天,直到当前日期。

现在我要做的是遍历dateseries 中的每一行值,并在dates 视图中检查该时间戳值(来自dateseries)是否大于first_day 列并且小于@987654330 @ 柱子。如果是,则数 1。所以它几乎是两个循环。第一个循环遍历dateseries 中的每个值,然后将其与dates 视图中的每一行进行比较,比较两列first_day 和last_day。我想另一种思考方式是,如果 dateseries 的值在日期视图中的 first_day 和 last_day 列之间,则计数为 1,否则为 0。

最后我想要一个看起来像这样的表(日期列与 June1 相同的时间序列 -> current_timestamp()):

|date|count|
|----|-----|
|2020-06-01 00:00:00 UTC|32|
|2020-06-02 00:00:00 UTC|31|
|2020-06-03 00:00:00 UTC|22|
|2020-06-04 00:00:00 UTC|5|
|2020-06-05 00:00:00 UTC|16|

...等等...

如何在 BigQuery SQL 中执行此操作?

编辑:不确定为什么表格语法不起作用...

【问题讨论】:

【参考方案1】:

以下是 BigQuery 标准 SQL

#standardSQL
with dateseries as (
  select date
  from unnest(GENERATE_TIMESTAMP_ARRAY('2020-06-01', CURRENT_TIMESTAMP(), INTERVAL 1 DAY)) AS date
)
select date, count(1) `count` 
from `project.dataset.dates`
join dateseries
on date between first_day and last_day
group by date

注意:project.dataset.dates 中的 first_day 和 last_day 列假定为时间戳数据类型。否则(如果它们是字符串) - 使用下面的行

on date between timestamp(first_day) and timestamp(last_day)

【讨论】:

这将返回一个查询,其中一行包含日期和计数作为列。每次我重新运行查询时,它都会返回一个随机日期和计数。不知道这里有什么问题。此外,当我运行 SELECT * FROM dateseries 时,它只返回 1 行... 您应该检查您的视图及其产生的内容。根据您的评论 - 它可能会自行产生随机数据。而不是这个 - 上面的答案应该(并且确实)按照您的问题提出的那样工作!!! 我刷新了我的页面并重新运行了查询,现在它可以工作了,谢谢!【参考方案2】:

您应该能够 date 上的 JOIN 两个表在 first_daylast_day 之间并计算行数:

SELECT ds.date, COUNT(d.first_day) AS count
FROM dateseries ds
JOIN dates d ON ds.date BETWEEN d.first_day AND d.last_day
GROUP BY ds.date
ORDER BY ds.date

请注意,并不是 100% 清楚您想要的日期结束条件;你可能想使用

JOIN dates d ON ds.date > d.first_day AND ds.date < d.last_day

【讨论】:

@JeStra 抱歉 - 没想到。我已经编辑了答案。

以上是关于迭代列中的时间戳行值并在 SQL 中执行 countif?的主要内容,如果未能解决你的问题,请参考以下文章

sql选择某一列的最大值与最小值并在同一列中显示

从另一个表中选择列中的相似值并在主表中使用另一个表值

选择最近的时间戳行并从具有 Variant DataType 的列中获取值

将行与标题进行比较,然后在列中插入值并在 VBA 中进行重复检查

Oracle SQL:比较 2 列中的所有值并交换它们

检查列中是不是存在值并在另一个 Pandas 中更改