如何在 Google BigQuery 中查找当月第一天和最后一天之间的值差异?

问题描述 投票:0回答:2

我有一个与此类似的数据集:

身份证 时间戳 值1 值2
1 2023-03-01 05:00:00 世界标准时间 1200 3.2
1 2023-03-15 05:00:00 世界标准时间 1400 2.4
1 2023-03-31 05:00:00 世界标准时间 2000 2.8
2 2023-03-01 05:00:00 世界标准时间 850 4
2 2023-03-15 05:00:00 世界标准时间 1250 4.1
2 2023-03-31 05:00:00 世界标准时间 3300 3.6

其中

Value 1
Value 2
每个
ID
每天同一时间服用一次。

Value 1
整个月的数量都在增加,而
Value 2
则没有。

我想找出每个

Value 1
每月最后一天和第一天
ID
的差异。

此外,我想找到每个

Value 2
每个月的最大值
ID

为每个值列创建两个单独的查询会更容易吗?或者有没有办法在同一个查询中完成每个任务?

sql google-bigquery
2个回答
0
投票

假设您的桌子名称是

Table

首先创建一个 CTE

ProcessedInfo
,以及一些额外的列以使我们的计算更容易,为此我们将使用窗口函数。

新增三个栏目如下:

  1. Value1_FirstDay_Month
    - 每年每月第一天的 Value1 值。为此,将使用
    FIRST_VALUE
    并按年和月分区,然后按时间戳升序排列
  2. Value1_LastDay_Month
    - 与上述相同,不同之处在于它是每月和每年最后一天的 Value1。对于这一列,我们将使用
    LAST_VALUE
    ,其分区和顺序与上一列相同。
  3. Value2_Max_ID_Month
    - 每个 ID、年份和月份的最大值 2。

然后,第二个 CTE

FinalResult
,我们使用第一个 CTE 中创建的列来计算所需的结果。

  1. 原始表的所有列。
  2. Value1_Diff
    -
    Value1_LastDay_Month
    Value1_FirstDay_Month
  3. 之间的区别
  4. Value2_Max_ID_Month
    - 与上面相同。无需计算,因为这是期望的结果。
WITH ProcessedInfo AS (

SELECT
 *,
 FIRST_VALUE(Value1) OVER(PARTITION BY EXTRACT(YEAR FROM Timestamp), EXTRACT(MONTH FROM Timestamp) ORDER BY Timestamp ASC) AS Value1_FirstDay_Month,
  LAST_VALUE(Value1) OVER(PARTITION BY EXTRACT(YEAR FROM Timestamp), EXTRACT(MONTH FROM Timestamp) ORDER BY Timestamp ASC) AS Value1_LastDay_Month,
 MAX(Value2) OVER(PARTITION BY ID, EXTRACT(YEAR FROM Timestamp), EXTRACT(MONTH FROM Timestamp)) AS Value2_Max_ID_Month
FROM Table
),

FinalResult AS (
 SELECT ID, Timestamp, Value1, Value2,
  (Value1_LastDay_Month - Value1_FirstDay_Month) AS Value1_Diff,
   Value2_Max_ID_Month
 FROM ProcessedInfo
)

SELECT * FROM FinalResult;

0
投票

实际上取决于您希望输出如何显示。无论如何,一个查询就可以了。

如果你想显示所有行,那么这里有一个方法:

您可以使用

window functions
为您计算这些值。在下面的示例中,您可以将 substring() 替换为所需的方法,以从 Big Query 中的时间戳中提取 YYYYMM。

select 
 id, 
 some_date, 
 value1,  
 value2, 
 max(value1) over (partition by id, substring(some_date, 1, 7)) - 
 min(value1) over (partition by id, substring(some_date, 1, 7)) as val1_diff, 
 max(value2) over (partition by id, substring(some_date, 1, 7)) as max_val2
from table1

但是,如果您只想在月份和 ID 级别进行聚合,则可以使用此方法(如果您选择,请再次将子字符串替换为您想要的方法)。

select 
 id, 
 substring(some_date, 1, 7) as yyyy_mm, 
 max(value1) - min(value1) as val1_diff, 
 max(value2) as max_vale
from table1
group by id, substring(some_date, 1, 7) 

参见 this fiddle,虽然是 MySQL,但窗口函数也可以在 BQ 中使用。

© www.soinside.com 2019 - 2024. All rights reserved.