Группа SSRS на основе двух столбцов

У меня есть отчет, в котором отображается список повторяющихся учетных записей на основе наших бизнес-правил. Это работает, когда одна новая учетная запись сопоставляется с другими существующими учетными записями. У меня возникают проблемы, когда несколько новых учетных записей совпадают с одним и тем же существующим дубликатом. Вот пример того, как это выглядит сейчас, сгруппированное по NewId:

NewID   MatchedID   FirstName   LastName    AddDate      Address        PhoneNumber
10      10          Holly       Johnson     4/18/2013    123 1St Rd.    123 456 7890
10      2           Hollie      Johnson     1/1/1990     123 1St Rd.    123 456 7890

11      11          Holley      Johnson     4/17/2013    123 1St Rd.    123-456-7890
11      2           Hollie      Johnson     1/1/1990     123 First Rd.  123 456 7890

50      50          William     Johnson     4/17/2013    999 2nd St.    222 222 2222
50      3           Bill        Jonson      1/2/1990     999 Second St. 222-222-2222

Учетные записи, имеющие совпадения, сами включены для сравнения.

Итак, есть ли способ сгруппировать эти похожие учетные записи вместе без дубликатов? Это должно выглядеть так:

GroupID  AcctID   FirstName   LastName    AddDate      Address        PhoneNumber
1        2        Hollie      Johnson     1/1/1990     123 First Rd.  123 456 7890
1        10       Holly       Johnson     4/18/2013    123 1St Rd.    123 456 7890
1        11       Holley      Johnson     4/17/2013    123 1St Rd.    123-456-7890
2        50       William     Johnson     4/17/2013    999 2nd St.    222 222 2222
2        3        Bill        Jonson      1/2/1990     999 Second St. 222-222-2222

Мне все равно, выполняется ли группировка в SQL или в SSRS. Потребуется ссылка на два столбца ID, поскольку имя, адрес и номер телефона могут отличаться. Мне также нужно назначить новый GroupID, чтобы их можно было сгруппировать в отчете.


person StevenWhite    schedule 18.04.2013    source источник
comment
Я не совсем уверен, что вы спрашиваете здесь. Можете ли вы предоставить следующее: образец исходных данных, результаты, которые вы в настоящее время получаете с этим образцом, и результаты, которые вы хотели бы получить с этим образцом.   -  person Ian Preston    schedule 19.04.2013
comment
Расширил примеры, как было предложено.   -  person StevenWhite    schedule 19.04.2013
comment
Как выбрать между New -> 10 Matched -> 2 и New -> 11 Matched -> 2 выше? Вы просто выбираете тот, у которого самый низкий NewID? Кроме того, вы хотите избавиться только от повторяющихся значений MatchedId или следует также учитывать все дополнительные поля адреса ›   -  person Ian Preston    schedule 19.04.2013
comment
Выбор между этими двумя был бы произвольным, их не следует считать отдельными. Все поля адреса и т. д. привязаны к MatchedId. Другими словами, я хочу сгруппировать отдельные связанные идентификаторы MatchedId.   -  person StevenWhite    schedule 19.04.2013


Ответы (1)


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

with NoDuplicates as
(
  select *
    , rownum = row_number() over (partition by MatchedID order by NewID)
  from Accounts
)
select   NewID
  , MatchedID
  , Name
  , AddDate
  , Address
  , phoneNumber
from NoDuplicates where rownum = 1

SQL Fiddle с демонстрацией.

Хотя нет причин, по которым вы не можете просто использовать GROUP BY, предполагая, что адресная информация тоже всегда дублируется:

select NewID = min(NewID)
  , MatchedID
  , Name
  , AddDate
  , Address
  , phoneNumber
from Accounts
group by MatchedID
  , Name
  , AddDate
  , Address
  , phoneNumber

SQL Fiddle с демонстрацией.

Оба они возвращают ожидаемый результат.

Изменить после комментария:

Вы можете сгруппировать связанные строки с помощью следующего оператора:

with NoDuplicates as
(
  select *
    , rownum = row_number() over (partition by MatchedID order by NewID)
  from Accounts
  where NewID <> MatchedID
)
select groupID = MatchedID
  , Acct = MatchedID
  , FirstName
  , AddDate
  , Address
  , phoneNumber
from NoDuplicates where rownum = 1
union all
select groupID = coalesce(am.MatchedID, a.NewID)
  , Acct = a.MatchedID
  , a.FirstName
  , a.AddDate
  , a.Address
  , a.phoneNumber
from Accounts a
  -- join to the corresponding matched account
  left join Accounts am on a.MatchedID = am.NewID and am.NewID <> am.MatchedID
where a.NewID = a.MatchedID
order by groupID, Acct

SQL Fiddle с демонстрацией.

Однако по сути это просто группировка по MatchedID. Если вам нужны нумерованные группы, начинающиеся с 1, вы можете добавить в оператор предложение DENSE_RANK:

with NoDuplicates as
(
  select *
    , rownum = row_number() over (partition by MatchedID order by NewID)
  from Accounts
  where NewID <> MatchedID
)
, GroupedAcct as
(
  select GroupID = MatchedID
    , Acct = MatchedID
    , FirstName
    , AddDate
    , Address
    , phoneNumber
  from NoDuplicates where rownum = 1
  union all
  select GroupID = coalesce(am.MatchedID, a.NewID)
    , Acct = a.MatchedID
    , a.FirstName
    , a.AddDate
    , a.Address
    , a.phoneNumber
  from Accounts a
    -- join to the corresponding matched account
    left join Accounts am on a.MatchedID = am.NewID and am.NewID <> am.MatchedID
  where a.NewID = a.MatchedID
)
select GroupID = Dense_Rank() over (order by GroupID)
  , Acct
  , FirstName
  , AddDate
  , Address
  , phoneNumber
from GroupedAcct
order by groupID, Acct

SQL Fiddle с демонстрацией.

person Ian Preston    schedule 19.04.2013
comment
Первый пример работает отлично. Пример Fiddle тоже был хорош. Спасибо! - person StevenWhite; 19.04.2013
comment
Адрес, номер телефона и т. д. действительно различаются, поэтому я не мог просто сгруппировать их. - person StevenWhite; 19.04.2013
comment
Тогда имеет смысл. Круто, рад, что помогло. - person Ian Preston; 19.04.2013
comment
Есть ли способ назначить каждой из этих новых групп идентификатор? Этот метод отфильтровывает дубликаты, но мне все еще нужен способ связать их друг с другом в отчете, иначе он не очень полезен. - person StevenWhite; 20.04.2013
comment
@StevenW, разве MatchedID не соответствует этому требованию? Если нет, не могли бы вы изменить вопрос, чтобы показать требуемые результаты. Извините, что снова прошу дополнительную информацию. - person Ian Preston; 21.04.2013
comment
@StevenW, спасибо за обновление, я думаю, теперь я понял... Я обновил пару похожих утверждений - одно просто группирует по MatchedID, а другое создает искусственный порядковый номер Идентификатор группы. Надеюсь, все это работает с вашими реальными данными. - person Ian Preston; 23.04.2013