SQL BigQuery — ошибка, по которой переменная не сгруппирована, хотя она есть

#sql #google-bigquery

#sql #google-bigquery

Вопрос:

Код SQL:

  SELECT community_table.community_name,
        community_table.id,
        DATE(timestamp) as date,
        ifnull(COUNT(distinct app_opened.user_id), 0) as num_opened_DAU,
        lag(COUNT(distinct app_opened.user_id)) OVER 
        (ORDER BY community_table.community_name, community_table.id, DATE(timestamp)) as pre_Value
        
        FROM *** app_opened

        LEFT JOIN (
          SELECT DISTINCT id, community_id_2, context_traits_first_name, context_traits_last_name
          FROM (
                SELECT *
                FROM ***,
                UNNEST (JSON_EXTRACT_ARRAY(context_traits_community_ids, "$")) as community_id_2
               ) 
          GROUP by community_id_2, id, context_traits_first_name, context_traits_last_name) as community_id_table
        ON community_id_table.id = app_opened.user_id

        LEFT JOIN (
          SELECT DISTINCT id, name as community_name
          FROM ***) as community_table
        ON TO_JSON_STRING(community_table.id) = community_id_table.community_id_2

        WHERE app_opened.user_id is not null AND 
              EXTRACT(DAYOFWEEK FROM DATE(timestamp)) = 2 AND
              community_table.community_name is not null
        GROUP BY community_table.community_name, community_table.id, DATE(timestamp)

  

Сообщение об ошибке:
введите описание изображения здесь

Я совершенно не понимаю, что здесь может быть не так, поскольку в ошибке говорится, что временная метка не сгруппирована, хотя я сгруппировал ее внизу. Я пытался включить только временную метку, а не дату (timestamp), но это разрушает данные таблицы, которые я пытаюсь создать, где я нахожу количество пользователей за один день. У кого-нибудь есть другие идеи? Моя цель — для одной строки получить данные предыдущей строки, но поскольку я группирую по определенным показателям, мне нужно убедиться, что они также упорядочены по ним. Большое вам спасибо!

Комментарии:

1. Вы должны поместить запрос в вопрос в виде текста , чтобы была некоторая надежда на то, что другие смогут его прочитать.

2. @Gordon только что отредактировал! Извините, новичок в StackOverflow

Ответ №1:

Я думаю, вам просто нужно изменить OVER part как:

 OVER (PARTITION BY community_table.community_name, community_table.id, DATE(timestamp)) as pre_Value
  

Обновить. Похоже, что проблема была вызвана использованием DATE() функции внутри OVER , поэтому ее можно решить, используя DATE(timestamp) внутри подзапроса и передавая псевдоним в OVER

Комментарии:

1. Спасибо за ответ! К сожалению, это, похоже, не работает, потому что для части OVER требуется предложение ORDER BY, и даже если я добавлю это предложение PARTITION BY в начало, все равно возникает проблема с тем, что временная метка не сгруппирована или агрегирована по

2. @EricSingh О, на самом деле извините за путаницу с GROUP BY в конце запроса, она должна быть там, поскольку вы используете агрегацию count() . Я удалил эту часть из своего ответа. Кстати, вы пробовали использовать оба partition by и order by внутри OVER ?

3. Не беспокойтесь, спасибо! Я пытался использовать как PARTITION BY , так и ORDER BY внутри OVER , но тогда это все равно выдает ошибку о том, что временную метку необходимо сгруппировать или объединить, но временная метка, на которую она ссылается на этот раз, находится внутри РАЗДЕЛА BY.

4. @EricSingh как насчет удаления DATE() ключевого слова? OVER (PARTITION BY community_table.community_name, community_table.id, timestamp ORDER BY community_table.community_name, community_table.id, timestamp)

5. Спасибо за предложение. Таким образом, удаление DATE() делает запрос действительным, но это не дает мне таблицу, которую я хочу. Без DATE() , timestamp в настоящее время показывает что-то вроде 2020-08-15 08:29:32.229 UTC , но с DATE(timestamp) это просто показывает 2020-08-15 , что я и хочу. Если я удалю ее, таблица будет перепутана и больше не будет подсчитывать количество активных пользователей, которые появляются на определенную дату, а скорее на ту секунду, которая не слишком полезна.