【问题标题】:Trying to better understand MYSQL subqueries and returning more than 1 row试图更好地理解 MYSQL 子查询并返回超过 1 行
【发布时间】:2023-03-26 07:38:02
【问题描述】:

这个问题是Is there a standard way to swap a query from an ID to a different column like 'name'?的后续问题

这个查询工作正常:

    SELECT manufacturers.id, manufacturers.name, models.model_manufacturer, models.model_part
    FROM models 
    INNER JOIN manufacturers 
    ON manufacturers.id = models.model_manufacturer
    WHERE model_part = (
        SELECT parts.id 
        FROM parts 
        WHERE parts.name = '{$part_name}')
    GROUP BY manufacturers.id
    ORDER BY name ASC

但是这个,当它遇到一个拥有多个模型的制造商时,会失败并显示“子查询返回超过 1 行”:

SELECT parts.id, models.id, models.model_part, models.model_manufacturer, models.name, models.year, models.weight
    FROM parts
    INNER JOIN models
    ON parts.id = models.model_part
    WHERE model_manufacturer = (
        SELECT manufacturers.id 
        FROM manufacturers 
        WHERE manufacturers.name = '{$manufacturer_name}') 
    && model_part = (
        SELECT parts.id 
        FROM parts 
        WHERE parts.name = '{$part_name}')

我不太明白的是,如果我只运行工作示例中的子查询,或者在第二个示例中单独运行子查询,它们都返回一个值。如果我运行任一整个查询,它们都会返回多个值。那么为什么一个错误而另一个没有呢?在 myPHPAdmin 中运行查询可以正常工作,但是当我尝试在我的 PHP 文件中执行它时失败。

【问题讨论】:

    标签: php mysql subquery


    【解决方案1】:

    但是这个,当它遇到一个拥有超过 单个模型,因“子查询返回超过 1 行”而失败

    MySQL = 运算符可以将一个值与另一个值进行比较。当子查询返回更多,然后是 1 个值时,它会感到困惑,因为它不知道与哪个比较。

    使用IN 运算符代替=:

    SELECT parts.id, models.id, 
        models.model_part, models.model_manufacturer, 
        models.name, models.year, models.weight
    FROM parts
    INNER JOIN models
    ON parts.id = models.model_part
    WHERE model_manufacturer = (
            SELECT manufacturers.id 
            FROM manufacturers 
            WHERE manufacturers.name = '{$manufacturer_name}') 
        && model_part IN (
            SELECT parts.id 
            FROM parts 
            WHERE parts.name = '{$part_name}')
    

    对不起,如果我把 IN 运算符放在不正确的位置。但我认为,model_part 的第二个子查询是正确的地方。

    【讨论】:

    • 这仍然为我返回相同的错误。如果我理解你对 = 运算符的看法,如果 SELECT Manufacturer.id FROM Manufacturer WHERE Manufacturers.name = '{$manufacturer_name}' 和 SELECT parts.id FROM 部分,它不应该在我原来的第二个例子中工作吗WHERE parts.name = '{$part_name}' 有一个结果,他们会这样做吗?运行良好的原始查询只是 WHERE model_manufacturer = {$manufacturer_id} && model_part = {$part_id}。我只是想用“名称”列代替结果。
    • 真的很抱歉,这些查询不是导致错误的原因。我做了更多的测试,发现它是一个单独的查询,紧随我认为的那个之后。就我而言,完全是新手错误。幸运的是,您使用 IN 的建议奏效了 :)
    【解决方案2】:

    上面的 IN 建议可能是最简单的想法。

    不过,我很想将其重新编码为 JOIN,使用 DISTINCT 删除重复项:-

    SELECT DISTINCT parts.id, models.id, models.model_part, models.model_manufacturer, models.name, models.year, models.weight
        FROM parts
        INNER JOIN models
        ON parts.id = models.model_part
        INNER JOIN manufacturers
        ON models.model_manufacturer = manufacturers.id AND manufacturers.name = '{$manufacturer_name}'
        INNER JOIN parts parts2 ON models.model_part = parts2.id AND parts.name = '{$part_name}'
    

    【讨论】:

    • 您是否会因为 INNER JOINS 会更快而受到诱惑?我只是不确定“INNER JOIN parts 2”到底在做什么。 part2 是某种别名吗?
    • 他们可以。像您使用的那些选择往往只会在它们是相关的子选择时引起问题(即,它们依赖于选择外部的值),我倾向于避免它们以避免错误地使用相关的选择。由于它与部件表连接两次,因此我为第二个部件表使用了别名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多