Почему этот подзапрос не может возвращать более одной строки? - PullRequest
0 голосов
/ 22 апреля 2019

Этот Запрос генерируется 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, но не могу понять, почему возникает проблема с возвратом двух строк. Я перепробовал много альтернатив.

В чем проблема?

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

Подзапросы, включенные в столбцы оператора SELECT, называются «скалярными подзапросами».Скалярный подзапрос должен иметь возможность генерировать только ноль или одну строку, поскольку его значение (скаляр) будет помещено в возвращаемую строку набора результатов запроса, где есть место только для одного значения.Следовательно, если подзапрос возвращает более одной строки, он не может использоваться непосредственно как столбец SELECT.

Одним из вариантов является принудительное создание не более одной строки, возможно, с использованием функции агрегирования, такой как MAX(), MIN(), COUNT() и т. Д.

Другим вариантом являетсяприсоединиться к подзапросу как «табличное выражение», где нет ограничений на количество возвращаемых строк.

0 голосов
/ 22 апреля 2019

Слишком долго для комментария.

Это не

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 ...)

также вернет более одной строки.

Вам нужно найти способ, чтобы внешний подзапрос не возвращал более одной строки, даже когда внутренний, возможно, с помощью функций агрегирования, таких как MIN или MAX. Кроме того, вам нужно найти способ различать строки во внутреннем подзапросе, которые имеют одинаковое значение MAX(encargosProveedor.fecha_entrega) (возможно, упорядочение по другому значению с LIMIT 1), чтобы запрос возвращал только одну строку.

...