По какой-то причине запрос возвращает все записи, кроме двух, хотя технически он соответствует критериям

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

Представим, что у меня есть этот список клиентов:

tblA
ClientID        FName         LName
1               Carol         Villa
2               Carol         Villa
3               Gainy         Brimes
4               Gainy         Brimes

И вот тот запрос, который я использую:

 select ClientID, FName, LName 
 from (select t.*,  count(*) over (partition by (substring(FName,0,4)), (substring(LName,0,4)), dob) as cnt  from tblClients t   ) t  
 where cnt > 1  
 order by  FName, LName

Если я запущу этот запрос к этой таблице, я получу только эти записи:

ClientID      FName        LName
1             Carol        Villa
2             Carol        Villa

Он не показывает мне Гейни Браймс, по какой причине?

Какая у вас база данных? Если это sql-сервер, substring - это не 0, как C#, а 1. Другими словами, substring(FName,0,4) - это то же самое, что и substring(FName,1,3). Однако это не объясняет вашу проблему.

HoneyBadger 10.08.2018 16:36

Где ваш столбец dob в данных выборки?

Yogesh Sharma 10.08.2018 16:37

SSMS 2012 @HoneyBadger

Koosh 10.08.2018 16:37

@YogeshSharma вот почему! DOB не совпадает для обоих клиентов, поэтому его не подтягивают.

Koosh 10.08.2018 16:38

Вы должны получить все четыре записи из этого запроса.

Ross Bush 10.08.2018 16:39

да, в моем случае DOB не соответствует, поэтому записи не извлекаются. Извините, что дождался вашего времени, ребята, моя ошибка.

Koosh 10.08.2018 16:40
0
6
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ответ уже обнаружил сам Куш. Поскольку DOB используется в разделении оконной функции, несоответствующий DOB может игнорировать некоторые из «предполагаемых» дубликатов.

Но вот небольшой тестовый сценарий, чтобы продемонстрировать этот эффект:

declare @tblClients table (ClientID int, FName varchar(30), LName varchar(30), dob int);
insert into @tblClients (ClientID, FName, LName, dob) values
 (1,'Carol','Villa',100)
,(2,'Carina','Vilpo',100)
,(3,'Garcy','Brimes',100)
,(4,'Garry','Bricks',200)
;

select ClientID, FName, LName
, dob, cnt, rn
, CASE WHEN cnt > 1 THEN 'Has Partial Dups' ELSE 'No Partials Dups' END as ThereBeDups
from 
(
 select ClientID, FName, LName, dob,  
 count(*) over (partition by dob, substring(FName,1,3), substring(LName,1,3)) as cnt,
 row_number() over (partition by dob, substring(FName,1,3), substring(LName,1,2) order by ClientID desc) as rn
 from @tblClients
) t
--where cnt > 1
order by  FName, LName;

Результат:

ClientID    FName   LName   dob cnt rn  ThereBeDups
--------    -----   -----   --- --- --  ----------------
2           Carina  Vilpo   100 2   1   Has Partial Dups
1           Carol   Villa   100 2   2   Has Partial Dups
3           Garcy   Brimes  100 1   1   No Partial Dups
4           Garry   Bricks  200 1   1   No Partial Dups

Другие вопросы по теме