SQL - 选择两列中具有相同值的行

Posted

技术标签:

【中文标题】SQL - 选择两列中具有相同值的行【英文标题】:SQL - select rows that have the same value in two columns 【发布时间】:2014-07-14 15:48:27 【问题描述】:

题目的解决方法是在回避我。

我有一个看起来像的表格(除了与我的问题无关的其他字段):

姓名、卡号、会员类型

现在,我想要一个显示卡号和成员类型相同的行的视图。这两个字段都是整数。名称是 VARCHAR。姓名不是唯一的,并且重复的卡号、会员类型也应显示为相同的姓名。

即如果以下是表格:

JOHN       | 324   | 2
PETER      | 642   | 1
MARK       | 324   | 2
DIANNA     | 753   | 2
SPIDERMAN  | 642   | 1
JAMIE FOXX | 235   | 6

我想要:

JOHN       | 324   | 2
MARK       | 324   | 2
PETER      | 642   | 1
SPIDERMAN  | 642   | 1

这可以按卡号排序,以使其对人类有用。

最有效的方法是什么?

【问题讨论】:

你试过select * from <table> where cardnumber = membertype吗? 您列出的记录的 cardnumber 和 membertype 值有何相同之处? 324 != 2 示例清楚地显示了输入和所需的输出。怎么有人糊涂了? 我们很困惑,因为措辞令人困惑、不正确。显然,他的意思是他想要基于这两个字段存在重复行的行。这不是“卡号和会员类型相同的行”。 通过示例,您可以完全忽略措辞。他们为自己说话。 【参考方案1】:

如果您只需要知道不唯一的 3 个字段的 值对,那么您可以这样做:

SELECT   concat(NAME, "|", CARDNUMBER, "|", MEMBERTYPE) AS myIdentifier, 
         COUNT(*) AS count
FROM     myTable 
GROUP BY myIdentifier
HAVING   count > 1

这将为您提供所有不同的 NAMECARDNUMBERMEMBERTYPE 对,它们被多次使用并计数(它们被重复了多少次)。这不会给您返回条目,您必须在第二步中执行此操作。

【讨论】:

【参考方案2】:

由于您提到名字可以重复,并且重复的名字仍然意味着不同的人并且应该出现在结果集中,我们需要使用 GROUP BY HAVING COUNT(*) > 1 才能真正检测到骗子。然后将其加入主表以获取完整的结果列表。

此外,由于从您的 cmets 中,听起来您正在将其包装到视图中,因此您需要分离出子查询。

CREATE VIEW DUP_CARDS
AS
SELECT CARDNUMBER, MEMBERTYPE
FROM mytable t2
GROUP BY CARDNUMBER, MEMBERTYPE
HAVING COUNT(*) > 1

CREATE VIEW DUP_ROWS
AS
SELECT t1.*
FROM mytable AS t1
INNER JOIN DUP_CARDS AS DUP
ON (T1.CARDNUMBER = DUP.CARDNUMBER AND T1.MEMBERTYPE = DUP.MEMBERTYPE )

SQL Fiddle Example

【讨论】:

Table后面的t1和t2是什么意思?像 select 命令的变量一样? 只是表别名。在子查询中将表与自身关联时需要。看here。 谢谢。我也会接受你的回答,但这似乎不可能。 如果你喜欢他的回答,可以点赞。我要指出,答案实际上并不合法,您不能使用“table”作为表名。 +1 假设他对此进行了编辑或注释。但是,这两个答案都会跳过名称相同的行。 已编辑答案以反映您的想法,Mrjoltcola。【参考方案3】:

最有效的方法是什么?

我相信JOIN 会比EXISTS 更有效率

SELECT t1.* FROM myTable t1
JOIN (
    SELECT cardnumber, membertype
    FROM myTable
    GROUP BY cardnumber, membertype
    HAVING COUNT(*) > 1
) t2 ON t1.cardnumber = t2.cardnumber AND t1.membertype = t2.membertype

查询计划:http://www.sqlfiddle.com/#!2/0abe3/1

【讨论】:

对不起,我不同意这样更有效率。您已经引入了 GROUP BY,尽管它可能取决于连接。另一个可能是嵌套循环,这是什么? @woot GROUP BY 查询运行一次,因为存在子查询针对表中的每一行运行 鉴于这个问题,我投票认为这是最正确的,因为它包括名称匹配的重复项,我们必须假设这是一种可能性,除非 OP 告诉我们他在所有 3 个列中都有唯一的约束。 @nickdnk - 在这种情况下,这是更正确的答案。其他 2 个寻找不同的名称来区分重复的列。如果这是 Oracle,那么 ROWID 或简单的主键将更适合其他答案。 伙计们,这并不比使用exists 更有效。它使用 joingroup by 聚合。查看执行计划,您将看到两者的区别。不过答案很好。【参考方案4】:

您可以为此使用exists

select * 
from yourtable y
where exists (
  select 1
  from yourtable y2 
  where y.name <> y2.name
    and y.cardnumber = y2.cardnumber
    and y.membertype = y2.membertype)
SQL Fiddle Demo

【讨论】:

以上是关于SQL - 选择两列中具有相同值的行的主要内容,如果未能解决你的问题,请参考以下文章

如何选择在两列中具有相同值集的行,从而连接第三列中的值?

如何选择在某列中具有相同值的所有行

用SQL拆分具有多个值的行

如何在SQL Server表列中查找相同值的行

pandas:删除两列中具有相同索引的行中的重复值

如何删除R中两列中具有相同值但ID不同的行[重复]