#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