具有两列

时间:2016-05-03 00:54:31

标签: mysql sql

我一直试图让子查询起作用,但我认为它需要加入,但我是数据库的新手,并且很难解决它的工作原理。

我需要根据connect中的三列从userprofile中收集一行,我所做的并不是这样。

SELECT * FROM userprofile WHERE user_id IN 
(SELECT connect.user_id, connect.connect_to_id FROM connect WHERE 
(user_id = '1' OR connect_to_id = '1') AND is_connected = '1' );

因为第二个SELECT列有两列,所以

错误
#1241 - Operand should contain 1 column(s)

在第二个连接中只列出一个列并不返回所有条目,只返回第一个测试符合的条目。

这是否必须通过JOIN完成,如果是这样的话怎么办?我尝试的每个连接都会导致返回userprofile表中的所有条目。

感谢您的帮助。

* UPDATE

我现在有两个查询。

SELECT u.* FROM userprofile u 
JOIN connect c ON (u.user_id = c.user_id OR u.user_id = c.connect_to_id) WHERE
    ((c.user_id = '1' OR c.connect_to_id = '1') AND c.is_connected = '1') AND u.user_id != '1'
GROUP BY u.id;

并且

SELECT u.* FROM userprofile u WHERE u.user_id IN 
(SELECT connect.user_id FROM connect WHERE connect.connect_to_id = '1' AND connect.is_connected = '1'
UNION ALL
SELECT connect.connect_to_id FROM connect WHERE connect.user_id = '1' AND connect.is_connected = '1') 

使用microtime的10000多个调用我有第二个使用Sub Query更快一点。

Join Query:4.6199560165405
Sub Query:4.0528790950775

然后我决定进行测试以了解原因并发现GROUP BY命令大大减慢了JOIN。所以删除GROUP BY后,我得到了这些数字。

Join Query:2.6410460472107
Sub Query:4.1510140895844

事实证明,我并不需要GROUP BY,因为我检查了u.user_id!=' 1'这就阻止了我遇到的同样问题。

所以问题是,使用GROUP BY皱眉?

4 个答案:

答案 0 :(得分:1)

我认为你有两个问题。其中一个是两个colmumns的事情。另一个是笛卡尔积。

试试这个:

SELECT * 
  FROM userprofile up
 WHERE up.user_id IN (SELECT connect.user_id
            FROM connect 
               WHERE connect.connect_to_id = '1'
               UNION ALL
              SELECT connect.connect_to_id 
            FROM connect 
               WHERE connect.user_id = '1') 
   AND is_connected = '1' ;

答案 1 :(得分:1)

可以通过join或子查询来完成。通常,MySQL连接更有效,因为在许多情况下,MySQL无法使用带有子查询的索引。因此,在您的情况下,带连接的查询将是:

SELECT u.*
FROM
    userprofile u
    JOIN connect c ON (u.user_id = c.user_id OR u.user_id = c.connect_to_id)
WHERE
    (c.user_id = '1' OR c.connect_to_id = '1') AND
    c.is_connected = '1'

答案 2 :(得分:0)

也许你可以使用exists

做你想做的事
SELECT u.*
FROM userprofile u
WHERE user_id IN 
      EXISTS (SELECT 1
              FROM connect c
              WHERE '1' IN (c.user_id, c.connect_to_id) AND
                    c.is_connected = '1' AND
                    u.user_id IN (c.user_id, c.connect_to_id)
             );

注意:如果id是数值,则不要在常量周围使用单引号。混合类型可能会使优化器混淆。

答案 3 :(得分:0)

@Pastor 当我在is_connected列检查中收到错误

时,我不得不对您的代码进行更新
SELECT * 
FROM userprofile up
    WHERE up.user_id IN (SELECT connect.user_id
        FROM connect 
            WHERE connect.connect_to_id = '1' AND connect.is_connected = '1'
        UNION ALL
        SELECT connect.connect_to_id 
            FROM connect 
                WHERE connect.user_id = '1' AND connect.is_connected = '1') 
相关问题