如何从具有多个具有相同名称的列的子查询中选择特定列?

时间:2014-01-29 18:30:37

标签: sql postgresql subquery

在阅读之前,忘记查询的复杂性,我认为回答我的问题并不重要。

我有这样的查询:

SELECT *, 
    case when E_S = 'E' then m.cantidad else 0 end cantidad_recibida,
    case when E_S = 'S' then m.cantidad else 0 end cantidad_vendida,
    case when E_S = 'S' then m.cantidad * v.precio_venta_unitario else 0 end ingresos,
    case when E_S = 'E' then m.cantidad * lote.precio_compra_unitario else 0 end gastos
    FROM movimiento m
    LEFT JOIN lote_recibido lote ON m.id_lote_recibido = lote.id_lote_recibido
    LEFT JOIN venta v ON m.id_venta = v.id_venta
    INNER JOIN ubicacion_producto up ON m.id_ubicacion = up.id_ubicacion AND m.id_producto = up.id_producto
    INNER JOIN ubicacion u ON up.id_ubicacion = u.id_ubicacion
    INNER JOIN almacen a ON u.id_almacen = a.id_almacen
    ORDER BY m.id_producto

此查询返回一个结果集,该结果集具有4个具有相同名称id_producto的列,这两个列都来自查询中的不同表,如下所示:

id_producto  |  ...  | id_producto  | ... | id_producto | ... | id_producto | ...
  1004                    null                 1004                1004
  1004                    null                 1004                1004
  1004                    1004                 null                1004

这是因为我正在加入其中4个有该列(id_producto)的表。

当我想将上述查询作为另一个查询的子查询时出现问题,如下所示:

SELECT t.id_producto,
       t.id_almacen,
       t.fecha_movimiento,
       sum(t.ingresos) - sum(t.gastos) as balance,
       sum(t.cantidad_vendida) cantidad_vendida,
       sum(t.cantidad_recibida) cantidad_recibida
FROM
    ( --start subquery
SELECT *, 
    case when E_S = 'E' then m.cantidad else 0 end cantidad_recibida,
    case when E_S = 'S' then m.cantidad else 0 end cantidad_vendida,
    case when E_S = 'S' then m.cantidad * v.precio_venta_unitario else 0 end ingresos,
    case when E_S = 'E' then m.cantidad * lote.precio_compra_unitario else 0 end gastos
    FROM movimiento m
    LEFT JOIN lote_recibido lote ON m.id_lote_recibido = lote.id_lote_recibido
    LEFT JOIN venta v ON m.id_venta = v.id_venta
    INNER JOIN ubicacion_producto up ON m.id_ubicacion = up.id_ubicacion AND m.id_producto = up.id_producto
    INNER JOIN ubicacion u ON up.id_ubicacion = u.id_ubicacion
    INNER JOIN almacen a ON u.id_almacen = a.id_almacen
    ORDER BY m.id_producto) t --end subquery
GROUP BY t.id_producto,
       t.id_almacen,
       t.fecha_movimiento
ORDER BY t.id_producto, t.fecha_movimiento, t.id_almacen

当我在select t.id_producto中包含时,由于子查询返回4个具有相同名称的列,因此dbms给出了以下错误:

ERROR:  the reference to the column «id_producto» is ambiguous
LINE 2: SELECT t.id_producto,
               ^

State:SQL:42702
Character: 9

主要问题是:

1。如果有许多具有相同名称的列,如何从子查询结果集中选择特定列?

评论:我想选择它来自id_producto表的movimiento列,也许我可以通过重命名该字段并选择{{{ 1}},但我正在寻找更好的标准解决方案。

其他信息:

  • 我必须说,在4个具有相同名称t.id_producto_renamed的列上,其中一些列有一个空值,因为我在上面的示例中发布(如果此信息可能有用)。
  • 此外,我对其他领域也存在同样的问题,但我想如果我得到这种情况的解决方案,其余字段将是微不足道的。
  • 我正在使用PostgreSQL-9.2。

修改

我已尝试通过重命名来完成,如上所述,我的具体问题已通过此查询更正:

id_producto

但我不想只解决我的问题,我想知道的是,是否有任何方法可以选择具有相同名称的另一列的特定列。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

可能你在子查询的SELECT语句中使用Asterisk *,我猜是因为你不想按名称枚举列。如果你能做到,这可能是一个解决方案,或者试试这个:

SELECT t.id_prod,
   t.id_almacen,
   t.fecha_movimiento,
   sum(t.ingresos) - sum(t.gastos) as balance,
   sum(t.cantidad_vendida) cantidad_vendida,
   sum(t.cantidad_recibida) cantidad_recibida
FROM
   ( --start subquery
SELECT id_prod=m.id_producto,*, 
case when E_S = 'E' then m.cantidad else 0 end cantidad_recibida,
case when E_S = 'S' then m.cantidad else 0 end cantidad_vendida,
case when E_S = 'S' then m.cantidad * v.precio_venta_unitario else 0 end ingresos,
case when E_S = 'E' then m.cantidad * lote.precio_compra_unitario else 0 end gastos
FROM movimiento m
LEFT JOIN lote_recibido lote ON m.id_lote_recibido = lote.id_lote_recibido
LEFT JOIN venta v ON m.id_venta = v.id_venta
INNER JOIN ubicacion_producto up ON m.id_ubicacion = up.id_ubicacion AND m.id_producto =      up.id_producto
INNER JOIN ubicacion u ON up.id_ubicacion = u.id_ubicacion
INNER JOIN almacen a ON u.id_almacen = a.id_almacen
ORDER BY m.id_producto) t --end subquery
GROUP BY t.id_producto,
   t.id_almacen,
   t.fecha_movimiento
ORDER BY t.id_producto, t.fecha_movimiento, t.id_almacen 

答案 1 :(得分:0)

如果您最终只想从id_producto表中选择movimento列,则可以调整子查询以仅选择该列。因此,您将删除SELECT *(您可能会考虑使用那么多连接),并且只获取您将要使用的列(以及case语句创建的列):

-- start subquery
SELECT
  m.id_producto,
  id_almacen,
  fecha_movimiento,
  ...

如果您确实需要选择所有不同的id_producto列,那么您可以执行以下操作(我认为这是您在评论中引用的内容):

-- start subquery
SELECT
  m.id_producto as id1,
  up.id_producto as id2,
  ...