选择其中一列出现在至少两个不同对中的列对

时间:2014-02-24 15:53:18

标签: mysql

我希望从MySQL表中选择一对不同的值,其中一列的值至少出现两次。

例如,我有下表:

+----+---------+----------+-----------+
| id | machine | filename | ipaddress |
+----+---------+----------+-----------+
| 1  | X       | /tmp/1   | 1.2.3.4   |
| 2  | X       | /tmp/2   | 1.2.3.4   |
| 3  | X       | /tmp/3   | 2.3.4.5   |
| 4  | Y       | /tmp/4   | 2.3.4.5   |
| 5  | Z       | /tmp/5   | 2.3.4.5   |
| 6  | Z       | /tmp/6   | 2.3.4.5   |
+----+---------+----------+-----------+

我希望选择至少两个ipaddress中存在特定machine的所有行。只需要一个machine - ipaddress - 对,因此结果为:

+---------+-----------+
| machine | ipaddress |
+---------+-----------+
| X       | 2.3.4.5   |
| Y       | 2.3.4.5   |
| Z       | 2.3.4.5   |
+---------+-----------+

我尝试过对机器和ipaddress进行分组:

SELECT machine, ipaddress FROM table 
GROUP BY machine, ipaddress HAVING count(*) > 1

但是,这也导致了(X,1.2.3.4)。

我也尝试使用子查询,但这只返回任何ipaddress一次:

SELECT machine, ipaddress FROM 
    (SELECT machine, ipaddress FROM table GROUP BY machine, ipaddress) t 
GROUP BY ipaddress HAVING count(*) > 1

我无法找到合适的查询。应该注意的是,该表相当大,并且需要有效的查询。

2 个答案:

答案 0 :(得分:1)

我目前没有MySQL在我面前,但我在SQL Server中尝试了以下内容,它似乎适用于您的问题。请务必编写一些单元测试来验证:

SELECT DISTINCT machine, ipaddress
FROM [table] t1
WHERE EXISTS (
 SELECT 1
   FROM [table] t2
  WHERE t1.ipaddress = t2.ipaddress
  GROUP BY ipaddress
 HAVING COUNT(DISTINCT machine) > 1);

这会产生您的数据:

+---------+-----------+
| machine | ipaddress |
+---------+-----------+
| X       | 2.3.4.5   |
| Y       | 2.3.4.5   |
| Z       | 2.3.4.5   |
+---------+-----------+

这种替代语法也有效,并且可能(或可能不)对MySQL更快(如果这对您很重要,请进行性能测试):

SELECT DISTINCT machine, ipaddress
FROM [table]
WHERE ipaddress IN (
 SELECT ipaddress
   FROM [table]
  GROUP BY ipaddress
 HAVING COUNT(DISTINCT machine) > 1);

答案 1 :(得分:0)

试试这个:

  SELECT machine, ipaddress FROM 
        (SELECT DISTINCT machine, ipaddress FROM table) t 
    GROUP BY ipaddress,machine HAVING count(*) > 1