2012-05-08 51 views
0

我的新創建的別名ABONO和CARGO存在問題。 ALIASES(用於結果的列名)和SQL查詢正常工作直到我嘗試計算「ABONO-CARGO AS AJUSTE」=> Interbase給出了一個錯誤,它不知道列「ABONO」。正確使用Interbase子查詢中的別名

動態SQL錯誤 SQL錯誤代碼= -206 列未知 ABONO

有什麼不對?

SELECT M."MOV_CUENTA", 
     (SELECT SUM(MM."MOV_MONTO") 
      FROM "movimientos" MM 
     WHERE MM."MOV_TIPOMOV" = 'A' AND MM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
     GROUP BY MM."MOV_CUENTA" 
     ) AS ABONO, 
     (SELECT SUM(XM."MOV_MONTO") 
      FROM "movimientos" XM 
     WHERE XM."MOV_TIPOMOV" = 'C' AND XM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
     GROUP BY XM."MOV_CUENTA" 
     ) AS CARGO, 
     ABONO-CARGO AS AJUSTE 
    FROM "cuentasSaldo" CS 
INNER JOIN "movimientos" M ON (CS."ID_CUENTAMUN" = M."MOV_CUENTA") 
INNER JOIN "ajustes" AA ON (M."ID_AJUSTE" = AA."ID_AJUSTE") 
INNER JOIN "documentos" DD ON (AA."ID_DOCUMENTO" = DD."ID_DOCUMENTO") 
WHERE M."ID_AJUSTE" IN 
      (SELECT A."ID_AJUSTE" 
       FROM "ajustes" A 
      WHERE A."ID_DOCUMENTO" IN 
        (SELECT D."ID_DOCUMENTO" 
         FROM "documentos" D 
         WHERE D."ID_EMPRESA" = 1 AND D."DOC_EDITABLE" = 1 
        ) 
      ) 
ORDER BY M."ID_AJUSTE", M."MOV_CUENTA" 
+0

真的需要你需要在查詢本身做一個簡單的field1-field2嗎?你不能在你的應用程序部分做這件事嗎?別名你提到的方式不適用於我知道的幾個dbs,所以FireBird的情況也是如此 – nawfal

+0

嗯,我在C++ Builder中編程,因爲我正在使用TDBGrid(C++)組件來填充數據源和數據集來填充我在向數據集添加計算字段時遇到了困難。數據集的__onCalcFields__事件沒有被解僱,所以我決定讓數據庫完成這部分,並計算費用和支付及其總和。 –

回答

2

簡潔地說,在許多SQL數據庫管理系統,在選擇列表中給出的列別名不能用在別處查詢中使用,甚至在選擇列表中的其他部分。

您將不得不在報告工具中進行計算,或者重複兩次查詢以獲取該值(這很痛苦,即使使用copy'n'paste —也只是一個理由,報告工具)。

SELECT M."MOV_CUENTA", 
     (SELECT SUM(MM."MOV_MONTO") 
      FROM "movimientos" MM 
     WHERE MM."MOV_TIPOMOV" = 'A' AND MM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
     GROUP BY MM."MOV_CUENTA" 
     ) AS ABONO, 
     (SELECT SUM(XM."MOV_MONTO") 
      FROM "movimientos" XM 
     WHERE XM."MOV_TIPOMOV" = 'C' AND XM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
     GROUP BY XM."MOV_CUENTA" 
     ) AS CARGO, 
     ((SELECT SUM(MM."MOV_MONTO") 
      FROM "movimientos" MM 
     WHERE MM."MOV_TIPOMOV" = 'A' AND MM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
     GROUP BY MM."MOV_CUENTA" 
     ) - 
     (SELECT SUM(XM."MOV_MONTO") 
      FROM "movimientos" XM 
     WHERE XM."MOV_TIPOMOV" = 'C' AND XM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
     GROUP BY XM."MOV_CUENTA" 
     )) AS AJUSTE 
    FROM "cuentasSaldo" CS 
INNER JOIN "movimientos" M ON (CS."ID_CUENTAMUN" = M."MOV_CUENTA") 
INNER JOIN "ajustes" AA ON (M."ID_AJUSTE" = AA."ID_AJUSTE") 
INNER JOIN "documentos" DD ON (AA."ID_DOCUMENTO" = DD."ID_DOCUMENTO") 
WHERE M."ID_AJUSTE" IN 
      (SELECT A."ID_AJUSTE" 
       FROM "ajustes" A 
      WHERE A."ID_DOCUMENTO" IN 
        (SELECT D."ID_DOCUMENTO" 
         FROM "documentos" D 
         WHERE D."ID_EMPRESA" = 1 AND D."DOC_EDITABLE" = 1 
        ) 
      ) 
ORDER BY M."ID_AJUSTE", M."MOV_CUENTA" 

在這些表達式中很容易失去孤獨的-

另一種方式來做到這一點是:

SELECT "MOV_CUENTA", ABONO, CARGO, (ABONO - CARGO) AS AJUSTE 
    FROM (SELECT M."ID_AJUSTE", 
       M."MOV_CUENTA", 
       (SELECT SUM(MM."MOV_MONTO") 
        FROM "movimientos" MM 
       WHERE MM."MOV_TIPOMOV" = 'A' AND MM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
       GROUP BY MM."MOV_CUENTA" 
       ) AS ABONO, 
       (SELECT SUM(XM."MOV_MONTO") 
        FROM "movimientos" XM 
       WHERE XM."MOV_TIPOMOV" = 'C' AND XM."MOV_CUENTA" = CS."ID_CUENTAMUN" 
       GROUP BY XM."MOV_CUENTA" 
       ) AS CARGO 
      FROM "cuentasSaldo" CS 
     INNER JOIN "movimientos" M ON (CS."ID_CUENTAMUN" = M."MOV_CUENTA") 
     INNER JOIN "ajustes" AA ON (M."ID_AJUSTE" = AA."ID_AJUSTE") 
     INNER JOIN "documentos" DD ON (AA."ID_DOCUMENTO" = DD."ID_DOCUMENTO") 
     WHERE M."ID_AJUSTE" IN 
        (SELECT A."ID_AJUSTE" 
         FROM "ajustes" A 
        WHERE A."ID_DOCUMENTO" IN 
          (SELECT D."ID_DOCUMENTO" 
           FROM "documentos" D 
           WHERE D."ID_EMPRESA" = 1 AND D."DOC_EDITABLE" = 1 
          ) 
        ) 
     ) AS X 
ORDER BY "ID_AJUSTE", "MOV_CUENTA" 

我想你也應該被選擇ID_AJUSTE,但是這是你的決定。我不確定你是否真的需要所有這些分隔標識符,但我基本上沒有將它們保留下來。

+0

極好的解決方案! – nawfal

+0

只有在標識符是關鍵字或需要區分大小寫的標識符時,才需要在Fireibrd中加引號標識符。 –

+0

@MarkRotteveel:所以,在這方面,Firebird是標準的SQL。標準SQL僅需要關鍵字的區分標識符,區分大小寫的標識符或包含不能處於普通標識符中的字符(例如空格和破折號)的標識符。 –

0

你應該在表「cuentasSaldo」(CS)中有一個字段ABONO,並且你有一個子查詢別名爲ABONO。所以你有兩個同名的「對象」。 我建議你嘗試在格式中調用字段:query.field。 行6中的示例: 而不是:ABONO-CARGO AS AJUSTE 使用:CS.ABONO-CARGO AS AJUSTE

+0

我沒有任何叫做ABONO/CARGO的字段。這來自表「movimientos」(運動) - 字段:MOV_TIPOMOV:「A」或「C」=>所以這不是一個模棱兩可的名字,但無論如何感謝。 –