Как сравнить столбцы записей из одной таблицы?

вот мои данные таблицы тестирования:

тестирование

ID      Name            Payment_Date   Fee                Amt
1       BankA           2016-04-01     100                20000
2       BankB           2016-04-02     200                10000
3       BankA           2016-04-03     100                20000
4       BankB           2016-04-04     300                20000

Я пытаюсь сравнить поля Name, Fee и Amt каждой записи данных, чтобы увидеть, есть ли одинаковые значения или нет. Если они имеют одинаковое значение, я хотел бы отметить что-то вроде " Y " на этой записи. Вот ожидаемый результат

ID      Name            Payment_Date   Fee                Amt      SameDataExistYN
1       BankA           2016-04-01     100                20000    Y
2       BankB           2016-04-02     200                10000    N
3       BankA           2016-04-03     100                20000    Y
4       BankB           2016-04-04     300                20000    N

Я пробовал эти два метода ниже. но я ищу любые другие решения, чтобы я мог выбрать лучший для своей работы.

способ 1.

select t.*, iif((select count(*) from testing where name=t.name and fee=t.fee and amt=t.amt)=1,'N','Y') as SameDataExistYN from testing t

Способ 2.

select t.*, case when ((b.Name = t.Name)
                        and (b.Fee = t.Fee) and (b.Amt = t.Amt)) then 'Y' else 'N' end as SameDataExistYN
from testing t
left join ( select Name,  Fee, Amt
            from testing
            Group By Name,  Fee, Amt
            Having count(*)>1  ) as b on b.Name = t.Name
                                      and b.Fee = t.Fee
                                      and b.Amt = t.Amt

4 ответов


вот еще один метод, но я думаю, что вам нужно запустить тесты на ваших данных, чтобы узнать, что лучше:

SELECT
  t.*,
  CASE WHEN EXISTS(
    SELECT * FROM testing WHERE id <> t.id AND Name = t.Name AND Fee = t.Fee AND Amt = t.Amt
  ) THEN 'Y' ELSE 'N' END SameDataExistYN
FROM
  testing t 
;

существует несколько подходов, с различиями в эксплуатационных характеристиках.

один из вариантов-запустить коррелированный подзапрос. Этот подход лучше всего подходит, если у вас есть подходящий индекс, и вы тянете сравнительно небольшое количество строк.

SELECT t.id
     , t.name
     , t.payment_date
     , t.fee
     , t.amt
     , ( SELECT 'Y' 
           FROM testing s
          WHERE s.name = t.name
            AND s.fee  = t.fee
            AND s.amt  = t.amt
            AND s.id  <> t.id
          LIMIT 1
        ) AS SameDataExist
  FROM testing t
 WHERE ...
 LIMIT ...

коррелированный подзапрос в списке выбора вернет Y, когда будет найдена хотя бы одна "соответствующая" строка. Если строка "matching" не найдена, столбец SameDataExist будет иметь значение NULL. Для преобразования NULL в 'N', вы можете обернуть подзапрос в функцию IFULL ().


Способ 2-это практичный подход. Выражение в списке выбора не должно выполнять все эти сравнения, они уже были сделаны в предикатах соединения. Все, что вам нужно знать, это была ли найдена соответствующая строка... достаточно просто проверить один из Столбцов на NULL/NOT NULL.

SELECT t.id
     , t.name
     , t.payment_date
     , t.fee
     , t.amt
     , IF(s.name IS NOT NULL,'Y','N') AS SameDataExists
  FROM testing t
  LEFT
  JOIN ( -- tuples that occur in more than one row
         SELECT r.name, r.fee, r.amt
           FROM testing r
          GROUP BY r.name, r.fee, r.amt
         HAVING COUNT(1) > 1
       ) s
    ON s.name = t.name
   AND s.fee  = t.fee
   AND s.amt  = t.amt
 WHERE ...

вы также можете использовать EXISTS (коррелированный подзапрос)


зацените

выберите оператор, чтобы найти дубликаты в определенных полях

Не уверен,как отметить это как обман...


выберите t.имя ,Т.плата,Т.АМТ,если(функция count(*)>1),'м','н') от тестирование группы по T.имя,Т.плата,Т.АМТ