Sql BigQuery中的平面有序值

Sql BigQuery中的平面有序值,sql,google-bigquery,Sql,Google Bigquery,在一个简单的查询中,我可以从这样的表中获取最后一个NOTNULL值吗 ID | Name | Inserted_at | Custom.Value1 | Custom.Value2 1 | Allan | 2017-08-01 | NULL | NULL 1 | NULL | 2017-08-03 | Value1 | NULL 1 | NULL | 2017-08-05 | Value2 | Value3 2 | Jones |

在一个简单的查询中,我可以从这样的表中获取最后一个NOTNULL值吗

ID | Name | Inserted_at | Custom.Value1 | Custom.Value2 1 | Allan | 2017-08-01 | NULL | NULL 1 | NULL | 2017-08-03 | Value1 | NULL 1 | NULL | 2017-08-05 | Value2 | Value3 2 | Jones | 2017-08-02 | NULL | NULL ID | Name |插入| Custom.Value1 | Custom.Value2 1 |艾伦| 2017-08-01 |零|零 1 |空| 2017-08-03 |值1 |空 1 |空| 2017-08-05 |值2 |值3 2 |琼斯| 2017-08-02 |零|零 我希望返回的值类似于:

1 | Allan | 2017-08-05 | Value2 | Value3 2 | Jones | 2017-08-02 | NULL | NULL 1 |艾伦| 2017-08-05 |价值2 |价值3 2 |琼斯| 2017-08-02 |零|零 我知道BigQuery的更新几乎是不可能的,一个天真的MAX/GROUP/orderby似乎并不正确

有人知道如何解决这个问题吗

谢谢

以下是一个示例:

#standardSQL
SELECT
  ID,
  ARRAY_AGG(Name IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Name,
  ARRAY_AGG(Custom.Value1 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value1,
  ARRAY_AGG(Custom.Value2 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value2
FROM YourTable
GROUP BY ID;
您可以使用示例数据尝试此操作:

#standardSQL
WITH YourTable AS (
  SELECT 1 AS ID, 'Allan' AS Name, DATE '2017-08-01' AS Inserted_at, STRUCT(CAST(NULL AS STRING) AS Value1, CAST(NULL AS STRING) AS Value2) AS Custom UNION ALL
  SELECT 1, NULL, DATE '2017-08-03', STRUCT('Value1' AS Value1, NULL AS Value2) UNION ALL
  SELECT 1, NULL, DATE '2017-08-05', STRUCT('Value2' AS Value1, 'Value3' AS Value2) UNION ALL
  SELECT 2, 'Jones', DATE '2017-08-02', STRUCT(NULL AS Value1, NULL AS Value2)
)
SELECT
  ID,
  ARRAY_AGG(Name IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Name,
  ARRAY_AGG(Custom.Value1 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value1,
  ARRAY_AGG(Custom.Value2 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value2
FROM YourTable
GROUP BY ID;
以下是一个例子:

#standardSQL
SELECT
  ID,
  ARRAY_AGG(Name IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Name,
  ARRAY_AGG(Custom.Value1 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value1,
  ARRAY_AGG(Custom.Value2 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value2
FROM YourTable
GROUP BY ID;
您可以使用示例数据尝试此操作:

#standardSQL
WITH YourTable AS (
  SELECT 1 AS ID, 'Allan' AS Name, DATE '2017-08-01' AS Inserted_at, STRUCT(CAST(NULL AS STRING) AS Value1, CAST(NULL AS STRING) AS Value2) AS Custom UNION ALL
  SELECT 1, NULL, DATE '2017-08-03', STRUCT('Value1' AS Value1, NULL AS Value2) UNION ALL
  SELECT 1, NULL, DATE '2017-08-05', STRUCT('Value2' AS Value1, 'Value3' AS Value2) UNION ALL
  SELECT 2, 'Jones', DATE '2017-08-02', STRUCT(NULL AS Value1, NULL AS Value2)
)
SELECT
  ID,
  ARRAY_AGG(Name IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Name,
  ARRAY_AGG(Custom.Value1 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value1,
  ARRAY_AGG(Custom.Value2 IGNORE NULLS ORDER BY Inserted_at LIMIT 1)[OFFSET(0)] AS Value2
FROM YourTable
GROUP BY ID;

您可以使用
第一个值()


您可以使用
第一个值()


这是我一直想要的聚合函数。它可以在MSSQL中使用窗口函数来完成,但与聚合相比效率非常低。我不知道BigQuery是否存在类似窗口的函数。为什么是value1而不是value2?@ChrisBerger实际上是为BigQuery存在的,但我不知道如何解决这个问题…@xQbert,我的坏。。。刚刚修正:)@AllanSene那么我认为下面的任何一个例子都会有所帮助。使用first_value()的方法是我如何使用窗口函数来实现这一点,但我讨厌使用
DISTINCT
和性能影响。我以前从未见过的ARRAY_AGG()函数。看起来正是你需要的,我希望我知道它的存在。我想知道它是否能避免窗口函数的性能问题?这是我一直想要的聚合函数。它可以在MSSQL中使用窗口函数来完成,但与聚合相比效率非常低。我不知道BigQuery是否存在类似窗口的函数。为什么是value1而不是value2?@ChrisBerger实际上是为BigQuery存在的,但我不知道如何解决这个问题…@xQbert,我的坏。。。刚刚修正:)@AllanSene那么我认为下面的任何一个例子都会有所帮助。使用first_value()的方法是我如何使用窗口函数来实现这一点,但我讨厌使用
DISTINCT
和性能影响。我以前从未见过的ARRAY_AGG()函数。看起来正是你需要的,我希望我知道它的存在。我想知道它是否能避免窗口函数的性能问题?实际上,我有很多嵌套的自定义值,所以我认为这种方法,使用CASE,是不可行的。。。无论如何谢谢:)实际上,我有很多嵌套的自定义值,所以我认为这种方法,使用CASE,是不可行的。。。无论如何谢谢:)你认为如果我在这个数组\u AGG中放一个DISTINCT子句,查询会更高效吗?一些自定义值可以是具有许多不同值的类别。如果您只查找单个值,为什么要使用DISTINCT?一般来说,我希望ORDER BY with LIMIT的性能更好。您认为如果我在这个数组_AGG中放入一个DISTINCT子句,查询会更高效吗?一些自定义值可以是具有许多不同值的类别。如果您只查找单个值,为什么要使用DISTINCT?总的来说,我希望ORDER BY with LIMIT的表现会更好。