Как сравнить столбцы записей из одной таблицы?
Вот мои данные таблицы тестирования:
тестирование
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
Я пытаюсь сравнить поля Имя, Плата и Сумма каждой записи данных, чтобы увидеть, есть ли одинаковые значения или нет. Если они получили одинаковое значение, я бы хотел отметить что-то вроде "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 ...
Коррелированный подзапрос в списке SELECT будет возвращать Y, если найдена хотя бы одна "совпадающая" строка. Если соответствующая строка не найдена, столбец SameDataExist будет иметь значение NULL. Чтобы преобразовать NULL в N, вы можете заключить подзапрос в функцию IFULL().
Ваш метод 2 является работоспособным подходом. Выражение в списке SELECT не должно выполнять все эти сравнения, они уже были сделаны в предикатах соединения. Все, что вам нужно знать, это то, была ли найдена соответствующая строка... достаточно просто проверить один из столбцов на 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.name,t.fee,t.amt, если (count(*)>1),'Y','N') из группы t тестирования по t.name, t.fee, t.amt