具有两列的MYSQL子查询
我一直试图让一个子查询工作,但我认为它需要加入,而不是,但我是新的数据库,有一个困难的时候,我的头脑围绕如何工作 我需要根据connect中的三列从userprofile中收集一行,但我没有这样做具有两列的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
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
,查看索引是什么