SQL row_number() — как игнорировать нули?

#sql #null #snowflake-cloud-data-platform #row-number

Вопрос:

Мне нужно добавить счетчики активности пользователей, используя этот запрос:

 select PERSON_ID, TIMESTAMP, 
  row_number() over (partition by  PERSON_ID order by  TIMESTAMP asc) as PERSON_COUNTER
from table1;
 

Это хорошо работает, но учитывается также случай, когда PERSON_ID равен null и назначает счетчики, как если бы null было именем пользователя. Я хочу, чтобы в этих случаях счетчик был равен нулю — есть идеи?

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

1. @Репортер, не кажется ли вам, что это такая ненужная придирка к довольно простому вопросу?

2. @Paul SQL имеет широкий спектр применения. И многие участники stackoverflow отметили SQL в списке тегов. Поэтому для первой фильтрации это сэкономит время, если вы сможете фильтровать на своей собственной начальной странице. И, как вы можете видеть, этот вопрос не является вопросом для специального sqlserver oracle и т. Д.

Ответ №1:

Да, вы можете использовать запрос, как показано ниже

 select 
PERSON_ID, TIMESTAMP, CASE WHEN PERSON_ID IS NULL THEN NULL ELSE PERSON_COUNTER END AS PERSON_COUNTER
from
(
select PERSON_ID, TIMESTAMP, 
  row_number() over (partition by  PERSON_ID order by  TIMESTAMP asc) as PERSON_COUNTER
from table1
) t;
 

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

1. @Stefanov.sm сделано

Ответ №2:

Это будет более элегантно и без подзапросов:

 select PERSON_ID, TIMESTAMP, 
  iff(PERSON_ID is null, null, row_number() over (partition by  PERSON_ID order by  TIMESTAMP asc)) as PERSON_COUNTER
from table1;
 

Ответ №3:

Лучше фильтровать нули

       select PERSON_ID, TIMESTAMP, 
     row_number() over (partition by  PERSON_ID order by  
     TIMESTAMP asc) as PERSON_COUNTER
     from table1 where PERSON_ID IS NOT NULL;
 

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

1. как насчет «счетчик в этом случае будет равен нулю»?

2. Зачем кому-то понадобились записи Nulls с разными временными метками, которым присвоены номера строк, в значительной степени полная чушь. Да, вы могли бы представлять значения null через объединение n показать для ваших предполагаемых проблем n также прочитайте слоган запроса Ops, в котором говорится «как игнорировать значения n».

3. Ну, это то, о чем просит операция.

Ответ №4:

Да, счетчик продолжает считать, но на самом деле вас не волнуют значения строк, в которых PERSON_ID значение равно нулю. Так что просто отбросьте их

 select PERSON_ID, 
       CASE PERSON_ID
         WHEN NULL THEN NULL
         ELSE PERSON_COUNTER
       END as PERSON_COUNTER
FROM (
  select PERSON_ID, TIMESTAMP, 
    row_number() over (partition by  PERSON_ID order by  TIMESTAMP asc) as PERSON_COUNTER
  from table1) T;
 

Или даже добавьте WHERE предложение на том же уровне, чтобы избавиться от строк, если они вам вообще безразличны

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

1. @DhruvJoshi добрался сюда немного быстрее, хотя =)

2. Но (во многих СУБД) оба они не работают без псевдонима производной таблицы …

3. Справедливое замечание. Отредактировал это в