Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.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(错误子查询返回超过1行)-但我期望超过1行_Mysql - Fatal编程技术网

MySQL(错误子查询返回超过1行)-但我期望超过1行

MySQL(错误子查询返回超过1行)-但我期望超过1行,mysql,Mysql,我希望有多行: SELECT * FROM OWNER WHERE OWNER.ID IN( ( SELECT ID FROM OWNER WHERE LAST_NAME LIKE '%pickles%' OR FIRST_NAME LIKE '%pickles%'

我希望有多行:

SELECT * FROM OWNER 

    WHERE OWNER.ID IN(
            (
            SELECT 
                ID 
            FROM OWNER 
            WHERE 
                LAST_NAME LIKE '%pickles%'
                OR FIRST_NAME LIKE '%pickles%'
            ),

            (
            SELECT 
                OWNER_ID 
            FROM VISITOR 
            WHERE 
                NAME LIKE '%pickles%'
                OR SIZE LIKE '%pickles%'
            ),

            (
            SELECT 
                OWNER_ID 
            FROM BOARDING 
            WHERE 
                COMMENTS LIKE '%pickles%'
                OR PERSONAL_BELONGINGS LIKE '%pickles%'
            )

        )
第二个子查询

FROM VISITOR 
        WHERE 
            NAME LIKE '%pickles%'
正在导致错误。 但我希望返回多行? 它应该从找到的行返回多个ID。 那么,为什么它会有这些多行的问题呢


谢谢。

我想您正在寻找一个
工会

SELECT * FROM OWNER 
WHERE OWNER.ID IN(

        SELECT ID 
        FROM OWNER 
        WHERE LAST_NAME LIKE '%pickles%'
            OR FIRST_NAME LIKE '%pickles%'

        UNION

        SELECT OWNER_ID 
        FROM VISITOR 
        WHERE NAME LIKE '%pickles%'
            OR SIZE LIKE '%pickles%'

        UNION

        SELECT OWNER_ID 
        FROM BOARDING 
        WHERE COMMENTS LIKE '%pickles%'
            OR PERSONAL_BELONGINGS LIKE '%pickles%'


    )
说明:

您的子查询在3个列中返回结果,如:

ID                     OWNER_ID               OWNER_ID1
-----------------------------------------------------------------
OWNER_Table_ids        Visitor_Table_ids      Boarding_Table_ids
使用
UNION
,它将返回如下结果:

ID   
-------------------
OWNER_table_ids
Visitor_table_ids
Boarding_table_ids

错误“Subquery返回的值超过1”仅仅意味着“超过1列”。

接受的答案确实提供了一个有效的解决方案,但对现有查询为什么不能按书面方式工作的解释不正确

子查询有多种类型,返回多种类型的结果

在您的查询中:

WHERE expr IN (( /* subq 1 */ ), ( /* subq 2 */ ), ( /* subq 3 */ )) 
…相当于

WHERE expr = ( /* subq 1 */ )
   OR expr = ( /* subq 2 */ )
   OR expr = ( /* subq 3 */ )
这是而且只能是三个相等比较。以这种方式使用的子查询必须在标量上下文中进行解释。。。而标量子查询只能返回一行或零行,因为子查询的结果将用作一个索引。对于服务器来说,以其他方式解释它是不合逻辑的:您可以使用相等比较将单个值与两个或更多值进行比较吗?没有

您的查询并不像看上去那样,要求服务器构建子查询的所有结果集,并测试OWNER.ID是否在()中
IN
该集。您的查询要求服务器构建一个最多包含三个标量值的集合,每个子查询一个标量值,并确定OWNER.ID是否是()中的
那个(可能小得多)集合。这些子查询中的任何一个都返回多行,这使得查询无效。你很幸运,它已经不起作用了。如果您选择了只匹配一行的数据,它现在就可以工作了,但是当您有更多匹配时,它就坏了

ERROR 1242 (21000): Subquery returns more than 1 row
如果您(人为地)将
LIMIT 1
添加到三个子查询中的每一个子查询中,您会发现该查询确实有效,这说明了我的观点。结果将是不完整的,但查询是有效的,这推翻了错误是关于“列”的断言。。。但是,正如所写的,它是,而且只能是一组标量

使用
UNION
进行重构可以向服务器阐明您的意图

请注意,如果错误是关于列的断言是正确的,则消息将不同:

ERROR 1241 (21000): Operand should contain 1 column(s)
现在,在解释了错误的实际原因之后,我还将提出另一种解决方案。如果你还没有,你应该在访客和登机牌上都有一个(所有者ID)索引。此解决方案与
UNION
解决方案之间的性能可能会有所不同,具体取决于各个表中数据的组成以及MySQL服务器的版本。这两种解决方案都不是最优的,因为类似于比较的中开头的需要完整地读取表或至少一个包含列(如果有)的索引。这是全表扫描或全索引扫描,“扫描”是指逐行扫描。结尾
%
很好;开头的
%
成本很高,因为它从列的左侧取消了模式的锚定,索引就是在左侧执行工作的。如果可以,在应用程序允许的任何地方删除它,以获得更好的性能,并为搜索列编制索引;如果您无法删除前导的
%
,至少要了解这是您将看到的性能的一个因素。这是B树索引的一般限制,而不是MySQL。你可能最终还想调查一下

请注意,
存在(选择*…)
不存在。特别值得注意的是,
*
只是一种惯例。您可以说
SELECT 1
SELECT TRUE
,这并不重要,因为实际上没有选择任何数据,而且
EXISTS()
没有返回任何内容,除了
TRUE
--子查询匹配目标表中的一行或多行--或者
FALSE
--它没有。请注意,这些查询引用外部查询中的一个值o.ID,因此

在这里,我们检查owner表中的匹配条件,然后,如果需要,我们检查VISITOR或BOARDING中是否存在匹配条件的行。如果一个名为“猫”的女人有一只名为“猫”的狗,而你正在搜索“猫”,那么我们将在OWNER中找到它,优化器可能能够避免搜索该用户的其他两个表,因为我们已经知道她是匹配的,无论出于何种原因


另请参见:

非常感谢@Ranging Bull。我认为个人选择会结合id。为什么多个ID被视为错误?它是想说它找到了重复项吗?@Kreeverp:当您在操作符中使用
时,子查询必须只返回1列进行查找。使用您的查询,它将返回3列。这就是错误所说的。子查询返回的值超过1表示“超过1列”。错误报告的是“行”而不是列,这有点令人困惑?@kreevp:为了更好地理解:这里一行表示单个值列表。
SELECT o.* 
  FROM OWNER o
 WHERE o.LAST_NAME LIKE '%pickles%'
    OR o.FIRST_NAME LIKE '%pickles%'
    OR EXISTS(SELECT * 
                FROM VISITOR v 
               WHERE v.OWNER_ID = o.ID 
                 AND (v.NAME LIKE '%pickles%' OR v.SIZE LIKE '%pickles%')
             )
    OR EXISTS(SELECT *
                FROM BOARDING b 
               WHERE b.OWNER_ID = o.ID 
                 AND (COMMENTS LIKE '%pickles%' OR PERSONAL_BELONGINGS LIKE '%pickles%')
             );