这是我的测试表数据:
测试
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
答案 0 :(得分:3)
有几种方法,性能特征存在差异。
一种选择是运行相关子查询。如果你有一个合适的索引,并且你拉的行数相对较少,这种方法最适合。
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(相关子查询)
答案 1 :(得分:2)
答案 2 :(得分:1)
这是另一种方法,但我认为您必须对数据进行测试才能找出最佳方法:
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
;
答案 3 :(得分:1)
从t.name,t.fee,t测试t组选择t.name,t.fee,t.amt,if(count(*)&gt; 1),'Y','N')。 AMT