2014-01-29 39 views
0

在閱讀之前,忘記查詢的複雜性,我認爲回答我的問題並不重要。如何從具有多個同名的列的子查詢中選擇特定列?

我有這樣的查詢:

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 

當我包括我的選擇t.id_producto,作爲子查詢返回4列具有相同名稱,數據庫管理系統給了我以下錯誤:

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

State:SQL:42702 
Character: 9 

的主要問題是:

1.如何選擇一個SPECI如果有許多具有相同名稱的列,則子查詢結果集中的fic列?

評論:我想選擇它來自movimientoid_producto列,也許我可以通過重命名,即場和選擇t.id_producto_renamed做到這一點,但我正在尋找一個更好的標準溶液。

附加信息:

  • 我必須說,在4列具有相同名稱id_producto,他們中的一些4列有一個空值,因爲我張貼在上面的例子中(如果該信息可能會有所幫助)。
  • 此外,我有與其他領域相同的問題,但我想,如果我得到這種情況下的解決方案,其餘領域將是微不足道的。
  • 我正在使用PostgreSQL-9.2。

編輯:

我試圖通過重命名做到這一點,因爲我上面說的,和我的具體問題已得到糾正與此查詢:

SELECT t.id_prodmov, 
     t.id_almov, 
     t.fecha_movimiento, 
     sum(t.ingresos) - sum(t.gastos) as balance, 
     sum(t.cantidad_vendida_mov) cantidad_vendida, 
     sum(t.cantidad_recibida_mov) cantidad_recibida 
FROM 
    (
SELECT *, 
    case when E_S = 'E' then m.cantidad else 0 end cantidad_recibida_mov, 
    case when E_S = 'S' then m.cantidad else 0 end cantidad_vendida_mov, 
    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 (SELECT *, id_producto as id_prodmov FROM movimiento WHERE id_producto=10004 or id_producto=44443) 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 (SELECT *, id_almacen as id_almov FROM almacen) a ON u.id_almacen = a.id_almov 
    ORDER BY m.id_producto) t 
GROUP BY t.id_prodmov, 
     t.id_almov, 
     t.fecha_movimiento 
ORDER BY t.id_prodmov, t.fecha_movimiento, t.id_almov 

但我不我只想解決我的問題,我想知道的是,如果有任何方法可以選擇具有相同名稱的另一列的特定列。

任何幫助,將不勝感激!

回答

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 
+0

我認爲(和測試)是'選擇id_prod = M。 id_producto'的語法不正確。你的想法是正確的,因爲我試圖在子查詢中更改'm.id_producto'的名稱,並且避免了錯誤,但是我想知道是否有另一種方法可以從其中選擇特定字段(包括重複的字段名稱)子查詢。然而,你也是對的,我寧願不要在select子句中輸入所有的字段,但如果需要的話,這不會成爲問題。感謝您對carexcer – carexcer

+1

的幫助,我不認爲在子查詢中有多個同名的多列的直接方式。但動態查詢可能是一個解決方案,其中可以使用不同的別名爲具有相同名稱的列動態生成查詢。 –

0

如果最終只需要選擇從movimentoid_producto列,你可以調整你的子查詢,只選擇一。所以,你會刪除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, 
    ... 
+0

我在測試時使用*,但我需要從連接結果集中選擇相當多的字段。但問題是當子查詢的結果返回許多具有相同名稱的字段時,是否可以從子查詢中選擇特定的字段。如果可能的話,該怎麼做。但是,感謝您的幫助 – carexcer

+0

如果您想要選擇所有'id_producto'列,那麼您的最佳解決方案可能會像您在評論中提到的那樣將它們別名。 – ppalms

相關問題