Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有两列的MYSQL子查询_Mysql_Sql - Fatal编程技术网

具有两列的MYSQL子查询

具有两列的MYSQL子查询,mysql,sql,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') A

我一直试图让一个子查询工作,但我认为它需要加入,而不是,但我是新的数据库,有一个困难的时候,我的头脑围绕如何工作

我需要根据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表中的所有条目

谢谢你的帮助

*更新

我现在有两个问题

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;

使用microtime的调用超过10000次,而使用子查询的第二次调用要快一点

Join Query:4.6199560165405
Sub Query:4.0528790950775
然后,我决定做一个测试来了解原因,并发现GROUPBY命令大大降低了连接速度。因此,删除组BY后,我得到了这些数字

Join Query:2.6410460472107
Sub Query:4.1510140895844
事实证明,我并不真的需要这个群组,因为我正在检查u.user_id!='1'这就解决了我的问题


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

也许您可以使用
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是数值,则不要在常量周围使用单引号。类型的混合可能会混淆优化器。

也许您可以使用
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是数值,则不要在常量周围使用单引号。类型的混合会使优化器感到困惑。

我认为您有两个问题。其中之一就是两个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' ;

我想你有两个问题。其中之一就是两个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' ;

它可以通过
连接
或子查询完成。通常使用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'

它可以通过
连接
或子查询完成。通常使用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'
@牧师 我必须更新你的代码,因为我在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') 
@牧师 我必须更新你的代码,因为我在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') 

你想要的逻辑是什么?您有一个显然不起作用的查询。示例数据和期望的结果是一个很大的帮助。如果connect表中的user\u id或connect\u to\u id为true且is\u connected为true,我希望从userprofile中找到所有行。我不认为userprofile的结构真的没有什么区别。你想要的逻辑是什么?您有一个显然不起作用的查询。示例数据和期望的结果是一个很大的帮助。如果connect表中的user\u id或connect\u to\u id为true且is\u connected为true,我希望从userprofile中找到所有行。userprofile的结构真的没有什么不同,我不认为。我想知道我是否可以使用两个sub,但不知道如何编写它。所有的工会都是我所缺少的。我将尝试一下,看看会发生什么。我想知道是否可以使用两个sub,但不知道如何编写。所有的工会都是我所缺少的。我将尝试一下,看看会发生什么。我想我看到了我在JOIN中错过的东西。所以userprofile中的u.user_id被设置为WHERE?之后返回的值,我假设您认为这是比下面由Pastor提供的解决方案更好的解决方案,因为它可以容忍错误,或者速度也提高了吗?这非常有效。他们的sql语法目前还不适合我。例如,我假设在这个参数上,它是这样映射的?WHERE是显而易见的,我已经添加了一个组,这对我来说也是有意义的。谢谢你的帮助@UnixOne@PaulNeale要解释联接查询:
ON
子句指定联接的约束;在这种情况下,它包含由您精确指定的联接约束-
u.user\u id
等于
c.user\u id
c.connect\u to\u id
WHERE
子句是我为您想要返回的特定行设置约束的地方。要回答速度问题,您应该进行测量,但经验法则是MySQL更喜欢连接。另外,您可以尝试在每个查询上运行
explain
,查看每个查询使用了哪些索引。感谢您回答这些问题。我想我看到了JOIN缺少的内容。所以userprofile中的u.user_id被设置为WHERE?之后返回的值,我假设您认为这是比下面由Pastor提供的解决方案更好的解决方案,因为它可以容忍错误,或者速度也提高了吗?这非常有效。他们的sql语法目前还不适合我。例如,我假设在这个参数上,它是这样映射的?WHERE是显而易见的,我已经添加了一个组,这对我来说也是有意义的。谢谢你的帮助@UnixOne@PaulNeale要解释联接查询:
ON
子句指定联接的约束;在这种情况下,它包含由您精确指定的联接约束-
u.user\u id
等于
c.user\u id
c.connect\u to\u id
WHERE
子句是我为您想要返回的特定行设置约束的地方。要回答速度问题,您应该进行测量,但经验法则是MySQL更喜欢连接。此外,您还可以尝试在每个查询上运行
explain
,查看索引是什么