如何比较来自相同 table 的记录列?
How do I Compare columns of records from the same table?
这是我的测试table数据:
测试
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
下面这两种方法我都试过了。但我正在寻找任何其他解决方案,以便为我的工作选择最好的解决方案。
方法一
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
方法二
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
看看这个
Select statement to find duplicates on certain fields
不确定如何将其标记为欺骗...
这是另一种方法,但我认为您必须 运行 测试您的数据以找出最佳方法:
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 ...
当至少找到一个 "matching" 行时,SELECT 列表中的相关子查询将 return 为 Y。如果未找到 "matching" 行,则 SameDataExist 列的值为 NULL。要将 NULL 转换为 'N',您可以将子查询包装在 IFULL() 函数中。
你的方法二是可行的方法。 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(相关子查询)
Select t.name ,t.fee,t.amt,if(count(*)>1),'Y','N')来自 t.name、t.fee、t.amt
的测试组
这是我的测试table数据:
测试
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
下面这两种方法我都试过了。但我正在寻找任何其他解决方案,以便为我的工作选择最好的解决方案。
方法一
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
方法二
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
看看这个
Select statement to find duplicates on certain fields
不确定如何将其标记为欺骗...
这是另一种方法,但我认为您必须 运行 测试您的数据以找出最佳方法:
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 ...
当至少找到一个 "matching" 行时,SELECT 列表中的相关子查询将 return 为 Y。如果未找到 "matching" 行,则 SameDataExist 列的值为 NULL。要将 NULL 转换为 'N',您可以将子查询包装在 IFULL() 函数中。
你的方法二是可行的方法。 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(相关子查询)
Select t.name ,t.fee,t.amt,if(count(*)>1),'Y','N')来自 t.name、t.fee、t.amt
的测试组