GROUP_CONCAT是一个分析函数,必须附带一个OVER子句

时间:2017-03-06 10:40:32

标签: google-bigquery

我正在尝试使用bigquery legacy sql进行查询:

表格中的数据在更新后会附加,所以首先我需要在查询之后进行最新更新信息的子选择(使用MAX(updatedOn))。 标签是一个重复的字段,带有字符串值。

df.filter($"Country".isNotNull || $"id".isNotNull || $"salary".isNotNull).count()

TAGS是重复字段,我正在尝试选择没有查询标记的用户。

如果我没有使用 group_concat ,如果用户至少有一个其他标记,那么它也会检索带有查询标记的用户(因为当你有重复的字段时,bigquery会返回多行)

因此,如果用户具有“x”和“query”标签,则此查询将返回它(我不想)。 但如果用户只有“查询”标签,则不会返回。

希望我足够清楚。 我尝试过flatten(mytable,tags)和相同的结果。

谢谢。

3 个答案:

答案 0 :(得分:0)

您可以使用不同的方法来获取最新的行,而不是MAX。我们将此设置视为一种视图。根据需要调整。

#legacySQL
SELECT * from (
select rank() over (partition by id order by bq.created DESC, bq.insert_id  desc) as _rank,
*
FROM [dataset:table]
) where _rank=1

要在遗留SQL中获取不包含某些内容的行,请执行以下操作:

where NOT services contains 'Google'

我的示例中的services是重复字段

答案 1 :(得分:0)

使用ARRAY_AGG ORDER BYLIMIT使用standard SQL更容易表达。使用此模式,您可以选择与最新updatedOn关联的行。例如,

#standardSQL
SELECT s.*
FROM (
  SELECT
    ARRAY_AGG(t ORDER BY updatedOn DESC LIMIT 1)[OFFSET(0)] AS s
  FROM YourTable AS t
  WHERE NOT EXISTS (
    SELECT 1 FROM UNNEST(tags) AS tag WHERE tag LIKE '%query%'
  )
  GROUP BY _id
);

以下是您可以尝试的独立示例:

#standardSQL
WITH YourTable AS (
  SELECT 1 AS _id, DATE '2017-02-28' AS updatedOn, ['foo', 'bar', 'baz'] AS tags UNION ALL
  SELECT 1, DATE '2017-02-01', ['query01', 'foo'] UNION ALL
  SELECT 2, DATE '2017-03-01', ['bar', '10 query'] UNION ALL
  SELECT 2, DATE '2017-03-03', ['baz'] UNION ALL
  SELECT 2, DATE '2017-03-05', ['query']
)
SELECT s.*
FROM (
  SELECT
    ARRAY_AGG(t ORDER BY updatedOn DESC LIMIT 1)[OFFSET(0)] AS s
  FROM YourTable AS t
  WHERE NOT EXISTS (
    SELECT 1 FROM UNNEST(tags) AS tag WHERE tag LIKE '%query%'
  )
  GROUP BY _id
);

答案 2 :(得分:0)

我理解你的问题的方法是 - 为每个_id获取最新的条目,并仅输出那些没有“查询”标签的人

以下是BigQuery的Legacy SQL和Standard SQL

的版本    

旧版SQL:

#legacySQL
SELECT _id 
FROM (
  SELECT 
    _id, 
    matches, 
    ROW_NUMBER() OVER(PARTITION BY _id ORDER BY updatedOn DESC)  AS latest 
  FROM (
    SELECT _id, updatedOn, SUM(tags LIKE '%query%' ) WITHIN RECORD AS matches
    FROM [mytable]
  )
)
WHERE matches = 0
AND latest = 1  

标准SQL:

#standardSQL
SELECT s._id
FROM (
  SELECT
    ARRAY_AGG(t ORDER BY updatedOn DESC LIMIT 1)[OFFSET(0)] AS s
  FROM `mytable` AS t
  GROUP BY _id
)
WHERE NOT EXISTS (
  SELECT 1 FROM UNNEST(s.tags) AS tag WHERE tag LIKE '%query%'
)