Запрос для выбора записей, принадлежащих только идентификатору и вспомогательному идентификатору

#sql #sql-server

#sql #sql-сервер

Вопрос:

Я пытаюсь создать запрос, чтобы возвращать только записи, связанные с заданным идентификатором и вспомогательным идентификатором. В случае, если условие не выполнено, я хотел бы вернуть вторую возможность, то есть вторую комбинацию ID, Sub-ID. Примечание: Данные имеют тысячи идентификаторов, но только 2 вспомогательных идентификатора на идентификатор.

Это пример входных записей:

     ID    |  Sub-id  | VALUE
  ------------------------------
     1    |     1    |  "T"
  ------------------------------
     1    |     1    |  "F"
  ------------------------------
     1    |     2    |  "Z"
  ------------------------------
     1    |     2    |  "G"
  

Желаемый результат:

     ID    |  Sub-id  | VALUE
  ------------------------------
     1    |     1    |  "T"
  ------------------------------
     1    |     1    |  "F"
  ------------------------------
  

Если у нас есть только записи, относящиеся ко второй комбинации для данного идентификатора, вывод должен быть:

     ID    |  Sub-id  | VALUE
  ------------------------------
     1    |     2    |  "Z"
  ------------------------------
     1    |     2    |  "G"
  

Я пытался получить это с помощью выражения CTE, но мне это не удалось. Этот подход привел к возврату только одной записи, учитывая мое условие.

Моя попытка:

  WITH CTE (ID,SUB-ID,DuplicateCount,VALUE) AS (
    SELECT 
        ID,
        Sub-id,
        ROW_NUMBER () OVER (PARTITION BY ID
        ORDER BY SUB-ID) as DUPLICATECOUNT,
        VALUE
    FROM TBL_SOURCE
  

Что я упускаю?

Ответ №1:

Если я правильно вас понял, вы хотите, rank() а не row_number() :

 select *
from (
    select t.*, rank() over(partition by id order by subid) rn
    from mytable t
) t
where rn = 1
  

rank() присваивает одинаковый номер записям, которые имеют одинаковые id и subid , в отличие от row_number() , что гарантирует уникальность последовательности.

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

1. Спасибо за помощь и бонусное объяснение! Эта функция rank() будет полезна в будущем.

Ответ №2:

Если вы хотите это только для данного идентификатора, вы можете использовать top with ties :

 select top (1) with ties t.*
from t
where id = 1
order by subid;
  

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

1. Спасибо за комментарий @Gordon Linoff, но у меня тысячи идентификаторов в наборе данных.