SELECT * FROM表WHERE colA和colB至少有3个相同

时间:2011-06-20 20:24:07

标签: mysql

我必须将这两个mySQL查询合并为一个。我复制了一个解决方案并在连接表上使用它。我正在查询有两列的连接表(标记为“to_”和“from_”)。 'to_'和'from_'都保存同一个表的id号。我需要以这样的方式组合这些查询:我得到的结果基于:[('from_'+'to_')> 3],其中'from_'和'to_'具有相同的值(即,它们引用相同的id)。

$query = "select * from nodes where nodeID in (
    select to_ from joinTable group by to_ having count(*) > 3
)";

...
$query = "select * from nodes where nodeID in (
    select from_ from joinTable group by from_ having count(*) > 3
)";

致谢:我正在使用基于解决方案的查询'Mr E'早些时候帮助过我。

3 个答案:

答案 0 :(得分:1)

您可以尝试(请参阅最后一段关于to_和from_匹配要求的重要通知):

SELECT X.to_, COUNT(*) 
FROM joinTable X, joinTable Y
WHERE
    X.to_ = Y.from_
GROUP BY X.to_
HAVING COUNT(*) > 2

或者

SELECT X.to_, COUNT(*) 
FROM joinTable X LEFT JOIN joinTable Y ON X.to_ = Y.from_
GROUP BY X.to_
HAVING COUNT(*) > 2

使用Mr E的测试数据:

CREATE TABLE `foo` (
  `id` int(1) DEFAULT NULL,
  `to_` varchar(5) DEFAULT NULL,
  `from_` varchar(5) DEFAULT NULL
);

INSERT INTO `foo` VALUES (1,'A','B'),(2,'B','A'),(3,'B','C'),(4,'X','C'),(4,'X','B');

通过发布:

,它将在中途工作
SELECT X.to_, Y.from_
FROM foo X LEFT JOIN foo Y ON X.to_ = Y.from_

然后会产生:

mysql> SELECT X.to_, Y.from_ /*--, COUNT(*) */
    -> FROM foo X LEFT JOIN foo Y ON X.to_ = Y.from_;
+------+-------+
| to_  | from_ |
+------+-------+
| A    | A     | 
| B    | B     | 
| B    | B     | 
| B    | B     | 
| B    | B     | 
| X    | NULL  | 
| X    | NULL  | 
+------+-------+
7 rows in set (0.00 sec)

并通过完整运行:

mysql> SELECT X.to_, COUNT(*)
    -> FROM foo X LEFT JOIN foo Y ON X.to_ = Y.from_
    -> GROUP BY X.to_
    -> HAVING COUNT(*) > 2;
+------+----------+
| to_  | COUNT(*) |
+------+----------+
| B    |        4 | 
+------+----------+

基本上,将表连接到自身,然后从两个表中生成N:N匹配记录列表,其中to_和from_匹配(无论是否在同一行),然后使用单个列并聚合其值最后的COUNT(*)。

而且,最重要的是,为什么我将HAVING COUNT(*)上的数字从3降低到2? N:N关系将发出N1 * N2记录(其中N1是第一个表上匹配记录的计数,第二个表上是N2)。因此,如果下限为3,那么我们在这两个表中只能有3条以上的记录,其中一条记录在其中一条中,然后3条记录在另一条记录中(以任何顺序排列)或2合1中的一条记录,然后另外2条记录中的记录从那里开始) - 否则在to_和from_字段上将没有匹配,这是我不确定的事情 - OP是否只想要在两个字段上显示值的记录或者是否有COUNT(*)单方面就足够了。但是,如果是后者,除了分离查询以单独处理每一列之外,我没有看到任何其他选项,因为有些人已经发布,因为这是我们正在处理的孤立的总和。如果针对大型表运行,则

答案 1 :(得分:0)

SELECT * FROM(
    SELECT nodeID, to_, count(*) cto_ FROM joinTable jta GROUP BY to_
    OUTER JOIN  
    SELECT from_, count(*) cfrom_ FROM joinTable jtb GROUP BY from_
    ON jta.nodeID = jtb.nodeID
) WHERE ((cto_ + cfrom) > 3) as tableA
INNER JOIN
node
ON node.nodeID = tableA.nodeID

我没有测试过以确保此代码编译并运行但我认为这通常是找到所需内容的正确方向 -

首先从表到

获取数量

然后从表格中获取来自的数量

最后将添加内容添加到两个表的标准中。

只要外部联接在同一个nodeID上,如果我理解我的代码,那么每个nodeID应该只有一个条目。

好的,我通过一个方便的数据库运行它,这里的实际代码适用于我的数据库(当然更改你的名字)

SELECT * FROM ( 
    SELECT * FROM
    (
        SELECT ticket_id, author_uid, count(*) cto_ 
        FROM strato_ticket GROUP BY author_uid
    ) as jta
    LEFT JOIN  
    (
        SELECT ticket_id as tid, uid, count(*) cfrom_ 
        FROM strato_ticket GROUP BY uid
    ) as jtb
    ON jta.ticket_id = jtb.tid
    WHERE ((cto_ + cfrom_) > 3)
)  as jt
INNER JOIN strato_invite
ON strato_invite.ticket_id = jt.tid

答案 2 :(得分:0)

这不漂亮,但是:

select * from nodes where nodeID in (
     select x from (
        select to_ as x, count(*) as num
        from joinTable group by to_
        union all
        select from_ as x, count(*) as num
        from joinTable group by from_
    ) as temp_table
    group by x having sum(num) > 3;
)

似乎不适用于OP。我只能说“在我的机器上工作” - 这是我使用的数据和确切查询:

CREATE TABLE `foo` (
  `id` int(1) DEFAULT NULL,
  `to_` varchar(5) DEFAULT NULL,
  `from_` varchar(5) DEFAULT NULL
);

INSERT INTO `foo` VALUES (1,'A','B'),(2,'B','A'),(3,'B','C'),(4,'X','C'),(4,'X','B');

查询:

select x from (
    select to_ as x, count(*) as num
    from foo group by to_
    union all
    select from_ as x, count(*) as num
    from foo group by from_
) as temp_table
group by x having sum(num) > 3;