Выбор строк, у которых row_number больше 1

#sql #google-bigquery

# #sql #google-bigquery

Вопрос:

У меня есть следующая таблица (с использованием bigquery):

ID год месяц продажи row_number
111 2020 11 1000 1
111 2020 12 2000 2
112 2020 11 3000 1
113 2020 11 1000 1

Есть ли способ, которым я могу выбирать строки, у которых номера строк больше единицы?

Например, мой желаемый результат:

ID год месяц продажи row_number
111 2020 11 1000 1
111 2020 12 2000 2

Я не хочу просто выбирать исключительно строки с row_number = 2, но также и row_number = 1 .

Исходный блок кода, который я использовал для первого результата таблицы, является:

 SELECT 
    id, 
    year, 
    month, 
    SUM(sales) AS sales, 
    ROW_NUMBER() OVER (PARTITIONY BY id ORDER BY id ASC) AS row_number
FROM 
    table
GROUP BY 
    id, year, month
 

Ответ №1:

Вы можете использовать оконные функции:

 select t.* except (cnt)
from (select t.*,
             count(*) over (partition by id) as cnt
      from t
     ) t
where cnt > 1;
 

Применительно к вашему запросу агрегации:

 SELECT iym.* EXCEPT (cnt)
FROM (SELECT id, year, month, 
             SUM(sales) as sales, 
             ROW_NUMBER() OVER (Partition by id ORDER BY id ASC) AS row_number
             COUNT(*) OVER(Partition by id ORDER BY id ASC) AS cnt
      FROM table
      GROUP BY id, year, month
     ) iym
WHERE cnt > 1;
 

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

1. боже. большое вам спасибо. вы спасаете жизнь. : D

Ответ №2:

Вы можете обернуть свой запрос, как показано в примере ниже

 select * except(flag) from (
  select *, countif(row_number > 1) over(partition by id) > 0 flag 
  from (YOUR_ORIGINAL_QUERY)
)
where flag   
 

таким образом, это может выглядеть как

 select * except(flag) from (
  select *, countif(row_number > 1) over(partition by id) > 0 flag 
  from (
    SELECT id, 
    year, 
    month, 
    SUM(sales) as sales, 
    ROW_NUMBER() OVER(Partition by id ORDER BY id ASC) AS row_number
    FROM table
    GROUP BY id, year, month
  )
)
where flag   
 

поэтому при применении к образцу данных в вашем вопросе — это приведет к выводу ниже

введите описание изображения здесь

Ответ №3:

Попробуйте это:

 with tmp as (SELECT id, 
year, 
month, 
SUM(sales) as sales, 
ROW_NUMBER() OVER(Partition by id ORDER BY id ASC) AS row_number
FROM table
GROUP BY id, year, month)
select * from tmp a where exists ( select 1 from tmp b where a.id = b.id and b.row_number =2)
 

Это так явно exists statement SQL