【问题标题】:Why can't this subquery return more than one row?为什么这个子查询不能返回多于一行?
【发布时间】:2019-09-11 04:53:43
【问题描述】:

这个查询是由 Django ORM 使用 RawSQL 生成的:

SELECT `productos`.`codigo_barras`, (
        SELECT
            articulos.costo_us * (1 + articulos.iva_coef)
        FROM
            articulos
        INNER JOIN (
                SELECT 
                    articulos.id, MAX(encargosProveedor.fecha_entrega)
                FROM
                    articulos, encargosProveedor_listado_articulos, encargosProveedor, itemArticulosProveedor
                WHERE
                    articulos.id = itemArticulosProveedor.articulos_id AND
                    encargosProveedor.id = encargosProveedor_listado_articulos.encargosproveedor_id
                GROUP BY
                    articulos.producto_id
            )
        AS ultimos ON articulos.id = ultimos.id
) AS `ultimo_precio` FROM `productos`

它给出了一个错误

1242 - 子查询返回多于 1 行

这是子查询

的结果
+----+--------------------------------------+
| id | MAX(encargosProveedor.fecha_entrega) |
+----+--------------------------------------+
|  1 |              2019-04-17              |
+----+--------------------------------------+
|  3 |              2019-04-17              |
+----+--------------------------------------+

我阅读了 MYSQL 文档,但我不明白为什么返回两行会有问题。我已经尝试了很多替代方案。

问题出在哪里?

【问题讨论】:

  • 这与您的previous question 中的问题相同:您需要将外部查询中的行与内部查询中的行相关联,例如通过WHERE articulos.producto_id = productos.id 或加入中间查询:... FROM productos INNER JOIN (SELECT ...) AS ultimo_precio ON ultimo_precio.producto_id = productos.id。显然你还需要从最里面到中间查询暴露producto_id
  • 谢谢恩德。是的,在阅读了回复和更多文档后,我发现了 相关子查询 的概念,并最终对此查询进行了适当的更改。
  • 对于那些有类似问题的人,我觉得很有帮助的一篇文章是:essentialsql.com/…
  • @Hernan 如果您确实找到了解决此问题的方法,您应该将其作为答案发布并接受。

标签: mysql django database subquery django-orm


【解决方案1】:

作为SELECT 语句的列包含的子查询称为“标量子查询”。标量子查询应该只能产生零或一行,因为它的值(标量)将放置在查询结果集的返回行中,其中只有一个值的空间。因此,如果子查询返回多于一行,则不能直接用作SELECT 列。

一种选择是强制它最多生成一行,可能使用聚合函数,例如MAX()MIN()COUNT() 等。

另一种选择是将子查询作为“表表达式”加入,其中对返回的行数没有限制。

【讨论】:

    【解决方案2】:

    评论太长了。

    这不是

    SELECT articulos.id, MAX(encargosProveedor.fecha_entrega) 
    FROM ...
    

    子查询就是问题所在。由于这是JOIN 表达式的一部分,因此允许返回多于一行。 然而,由于返回不止一行,所以周围的子查询:

    SELECT articulos.costo_us * (1 + articulos.iva_coef)
    FROM articulos
    INNER JOIN (SELECT articulos.id, MAX(encargosProveedor.fecha_entrega)
                FROM ...)
    

    还会返回不止一行。

    您需要找到一种方法来防止外部子查询返回多行,即使内部子查询返回多行,可能通过使用聚合函数,例如 MINMAX。或者,您需要找到一种方法来区分内部子查询中具有相同 MAX(encargosProveedor.fecha_entrega) 值的行(可能按具有 LIMIT 1 的另一个值排序),以便查询只返回一行。

    【讨论】:

      猜你喜欢
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多