2015-10-12 5 views
0

Я знаю, что этот вопрос задавался несколько раз, но я до сих пор не могу понять, почему мой запрос возвращает значения, которые не являются дубликатами. Я хочу, чтобы мой запрос возвращал только записи, которые имеют одинаковое значение в столбце Credit. Запрос выполняется без ошибок, но также возвращаются значения, которые не дублируются. Это мой вопрос:Найти дубликаты в таблице MS SQL

Select 
    _bvGLTransactionsFull.AccountDesc, 
    _bvGLAccountsFinancial.Description, 
    _bvGLTransactionsFull.TxDate, 
    _bvGLTransactionsFull.Description, 
    _bvGLTransactionsFull.Credit, 
    _bvGLTransactionsFull.Reference, 
    _bvGLTransactionsFull.UserName 
From 
    _bvGLAccountsFinancial Inner Join 
    _bvGLTransactionsFull On _bvGLAccountsFinancial.AccountLink = 
    _bvGLTransactionsFull.AccountLink 
Where 
    _bvGLTransactionsFull.Credit 

IN 
    (SELECT Credit AS NumOccurrences 
FROM _bvGLTransactionsFull 
GROUP BY Credit 
HAVING (COUNT(Credit) > 1)) 


Group By 
    _bvGLTransactionsFull.AccountDesc, _bvGLAccountsFinancial.Description, 
    _bvGLTransactionsFull.TxDate, _bvGLTransactionsFull.Description, 
    _bvGLTransactionsFull.Credit, _bvGLTransactionsFull.Reference, 
    _bvGLTransactionsFull.UserName, _bvGLAccountsFinancial.Master_Sub_Account, 
    IsNumeric(_bvGLTransactionsFull.Reference), _bvGLTransactionsFull.TrCode 
Having 
    _bvGLTransactionsFull.TxDate > 01/11/2014 And 
    _bvGLTransactionsFull.Reference Like '5_____' And 
    _bvGLTransactionsFull.Credit > 0.01 And 
    _bvGLAccountsFinancial.Master_Sub_Account = '90210' 
+0

Но, у вас есть эти повторяющиеся данные? Кроме того, уверены ли вы, что условия 'HAVING' из вашего внешнего запроса не фильтруют данные? Я думаю, что выполнение всего запроса до самой «GROUP BY» обязательно вернет вам то, что вы хотите (* если соответствующие данные есть *). –

ответ

0

Это потому, что вы соответствуете по полю кредита обратно в таблицу, содержащую дубликаты. Вы должны выделить строки, которые дублируются с ROW_NUMBER:

;WITH CTE AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY CREDIT ORDER BY (SELECT NULL)) AS RN 
FROM _bvGLTransactionsFull) 
Select 
    CTE.AccountDesc, 
    _bvGLAccountsFinancial.Description, 
    CTE.TxDate, 
    CTE.Description, 
    CTE.Credit, 
    CTE.Reference, 
    CTE.UserName 
From 
    _bvGLAccountsFinancial Inner Join 
    CTE On _bvGLAccountsFinancial.AccountLink = CTE.AccountLink 
WHERE CTE.RN > 1 
Group By 
    CTE.AccountDesc, _bvGLAccountsFinancial.Description, 
    CTE.TxDate, CTE.Description, 
    CTE.Credit, CTE.Reference, 
    CTE.UserName, _bvGLAccountsFinancial.Master_Sub_Account, 
    IsNumeric(CTE.Reference), CTE.TrCode 
Having 
    CTE.TxDate > 01/11/2014 And 
    CTE.Reference Like '5_____' And 
    CTE.Credit > 0.01 And 
    _bvGLAccountsFinancial.Master_Sub_Account = '90210' 

Так же, как примечание стороны, я хотел бы рассмотреть вопрос об использовании псевдонимов, чтобы сократить ваши запросы и сделать их более читаемыми. Префикс имени таблицы перед каждым столбцом в соединении очень трудно читать.

+0

Вы фактически фильтруете строки, если вы получаете кредиты, которые имеют повторяющиеся значения в столбце «Кредит», вы всегда фильтруете первую строку ** дубликатов. Итак, если у него будет 2 дубликата суммы «Кредит», он все равно его увидит. –

+0

Изоляция/фильтр, у всех нас есть свои собственные педантичные термины для одного и того же. –

+0

Он хочет дублировать строки, а не первые строки каждого кредита. Поэтому имеет смысл отказаться от этой первой строки. –

0

Я доверяю вашему коду с точки зрения извлечения всех данных по вашим критериям. С этим, позвольте мне иметь другой подход и увидеть ваш сценарий «как есть». Итак, давайте сначала сохраним все записи в temp.

Select 
    _bvGLTransactionsFull.AccountDesc, 
    _bvGLAccountsFinancial.Description, 
    _bvGLTransactionsFull.TxDate, 
    _bvGLTransactionsFull.Description, 
    _bvGLTransactionsFull.Credit, 
    _bvGLTransactionsFull.Reference, 
    _bvGLTransactionsFull.UserName 
-- temp table 
INTO #tmpTable 
From 
    _bvGLAccountsFinancial Inner Join 
    _bvGLTransactionsFull On _bvGLAccountsFinancial.AccountLink = 
    _bvGLTransactionsFull.AccountLink 
Where 
    _bvGLTransactionsFull.Credit 

IN 
    (SELECT Credit AS NumOccurrences 
FROM _bvGLTransactionsFull 
GROUP BY Credit 
HAVING (COUNT(Credit) > 1)) 


Group By 
    _bvGLTransactionsFull.AccountDesc, _bvGLAccountsFinancial.Description, 
    _bvGLTransactionsFull.TxDate, _bvGLTransactionsFull.Description, 
    _bvGLTransactionsFull.Credit, _bvGLTransactionsFull.Reference, 
    _bvGLTransactionsFull.UserName, _bvGLAccountsFinancial.Master_Sub_Account, 
    IsNumeric(_bvGLTransactionsFull.Reference), _bvGLTransactionsFull.TrCode 
Having 
    _bvGLTransactionsFull.TxDate > 01/11/2014 And 
    _bvGLTransactionsFull.Reference Like '5_____' And 
    _bvGLTransactionsFull.Credit > 0.01 And 
    _bvGLAccountsFinancial.Master_Sub_Account = '90210' 

Затем удалите данные «единого входа», создав индекс строки и удалив все эти 1 временные индексы.

SELECT * FROM (
SELECT 
    ROW_NUMBER() OVER (PARTITION BY Credit ORDER BY Credit) AS rowIdx 
    , * 
FROM #tmpTable) AS innerTmp 
WHERE 
    rowIdx != 1 

Вы можете изменить свои предпочтения через PARTITION BY <column name>. Если у вас есть какие-либо проблемы, пожалуйста, поднимите его первым, поскольку они до сих пор поняли ваше дело.

EDIT: включить те кредиты, у которых есть дубликаты.

SELECT 
    tmp1.* 
FROM #tmpTable tmp1 
RIGHT JOIN (
     SELECT 
      Credit 
     FROM (
      SELECT 
       ROW_NUMBER() OVER (PARTITION BY Credit ORDER BY Credit) AS rowIdx 
       , * 
      FROM #tmpTable) AS innerTmp 
      WHERE 
       rowIdx != 1 
     ) AS tmp2 
ON tmp1.Credit = tmp2.Credit 
+0

Ваш запрос работает отлично, однако, извините, если мой вопрос был недостаточно ясным, но я все еще хочу, чтобы другие экземпляры дублирующей записи отображались. Например, если у меня есть две записи с кредитом 10.00, мне нужно увидеть обе записи. – elstiv

+0

Это имеет смысл, см. Мое редактирование. Мы должны иметь право править (правый стол слева), чтобы отфильтровать только дубликаты кредитов. –

Смежные вопросы