2015-01-04 5 views
5

私はh2データベースを利用した課金システムを開発中です。私は、ACCOUNTSTRANSACTIONSTEMPLATE_TRANSACTIONSテーブルからデータを集めるためにいくつかのビューを持っています。h2 VIEWは正しいSELECT文に問題があります

問題、私はその後、CREATE VIEW VIEW_TEMPLATES_DATAと内部SELECTSELECT * FROM VIEW_TEMPLATES_DATAを行くことを使用する場合、私は私のVIEW_TEMPLATES_DATAビューで表示する必要があり、正確にデータを生成SELECT文を持っているが、一言で言えば

、h2は私に語っ中その中の列の1つを見つけることができません。 h2は「裸の」SELECTステートメントで完全に満足していますが、CREATE VIEWステートメントにパッケージ化されていれば、それでは幸せではありませんか?

この投稿の長さをお詫び申し上げますが、SELECTステートメントはかなり長く複雑である必要があり、必要な背景情報があります。この投稿には、興味のある人のために、小さなテストデータベースを構築するために必要なすべてのSQLが含まれています。

背景

テンプレートトランザクションは「プロトタイプ」の形で使用頻度の高い取引を格納する方法です:テンプレートの取引のための唯一の要件は、それがナレーションを持っているということです。日付、金額、口座などはすべてオプションです。

アカウントには、アカウントが調整されたときに自動的にインスタンス化できるテンプレートトランザクションが関連付けられている場合があります。これは、例えば、クレジットカード口座の場合に非常に便利です。

もちろん、テンプレートトランザクションの「足」は、ヘッダ情報を格納するテーブルとは別のテーブルに格納されます。

そこで、我々は(当然、本物から簡体字)以下の表とビューを持っている:ここでは

ACCOUNTS 
ID NAME   PAYER_TEMPLATE_ID CURRENCY_ID 
------------------------------------------------- 
95 account0  null    1 
122 account1  47     0 
178 foo bar  35     0 

TEMPLATE_TRANSACTIONS 
ID NARRATION 
-------------- 
32 template0 
35 template1 
47 template2 

TEMPLATE_TRANSACTION_LEGS 
ID HEAD_TABLE_ID ACCOUNT_ID AMOUNT 
---------------------------------------- 
23 32    95   null 
74 35    178   500 
75 35    null   -500 

VIEW_TEMPLATES_DATA 
HEAD_ID NARRATION LEG_ID ACCOUNT_ID AMOUNT CURRENCY_ID 
---------------------------------------------------------------- 
23  template0 23  95   null  1 
35  template1 74  178   500  0 
35  template1 75  null   -500  null 
47  template2 null  null   null  null 

は、上記のコードです:

CREATE TABLE TEMPLATE_TRANSACTIONS(
    ID BIGINT NOT NULL PRIMARY KEY, 
    NARRATION VARCHAR NOT NULL DEFAULT ' ' 
); 

CREATE TABLE CURRENCIES(
    ID BIGINT NOT NULL PRIMARY KEY, 
    DESCRIPTION VARCHAR DEFAULT '' 
); 

CREATE TABLE ACCOUNTS(
    ID BIGINT NOT NULL PRIMARY KEY, 
    NAME VARCHAR DEFAULT '', 
    PAYER_TEMPLATE_ID BIGINT, 
    CURRENCY_ID BIGINT NOT NULL 
); 
ALTER TABLE ACCOUNTS ADD CONSTRAINT ACCOUNTS_FK_2 FOREIGN KEY(CURRENCY_ID) REFERENCES CURRENCIES(ID); 
ALTER TABLE ACCOUNTS ADD CONSTRAINT ACCOUNTS_FK_3 FOREIGN KEY(PAYER_TEMPLATE_ID) REFERENCES TEMPLATE_TRANSACTIONS(ID); 

CREATE TABLE TEMPLATE_TRANSACTION_LEGS(
    ID BIGINT NOT NULL PRIMARY KEY, 
    HEAD_TABLE_ID BIGINT NOT NULL, 
    ACCOUNT_ID BIGINT DEFAULT NULL, 
    AMOUNT INT DEFAULT NULL 
); 
ALTER TABLE TEMPLATE_TRANSACTION_LEGS ADD CONSTRAINT TEMPLATE_TRANSACTION_LEGS_FK_1 FOREIGN KEY(HEAD_TABLE_ID) REFERENCES TEMPLATE_TRANSACTIONS(ID); 
ALTER TABLE TEMPLATE_TRANSACTION_LEGS ADD CONSTRAINT TEMPLATE_TRANSACTION_LEGS_FK_2 FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID); 

CREATE VIEW VIEW_TEMPLATES_DATA AS (SELECT 
    TEMPLATE_TRANSACTIONS.ID  AS HEAD_ID, 
    TEMPLATE_TRANSACTIONS.NARRATION, 

    TEMPLATE_TRANSACTION_LEGS.ID  AS LEG_ID, 
    TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID, 
    TEMPLATE_TRANSACTION_LEGS.AMOUNT, 
    ACCOUNTS.CURRENCY_ID 
    FROM (TEMPLATE_TRANSACTIONS LEFT OUTER JOIN TEMPLATE_TRANSACTION_LEGS ON TEMPLATE_TRANSACTION_LEGS.HEAD_TABLE_ID = TEMPLATE_TRANSACTIONS.ID) 
     LEFT OUTER JOIN ACCOUNTS ON TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID = ACCOUNTS.ID 
); 

INSERT INTO CURRENCIES (ID, DESCRIPTION) VALUES (0, 'currency0'); 
INSERT INTO CURRENCIES (ID, DESCRIPTION) VALUES (1, 'currency1'); 
INSERT INTO TEMPLATE_TRANSACTIONS (ID, NARRATION) VALUES (32, 'template0'); 
INSERT INTO TEMPLATE_TRANSACTIONS (ID, NARRATION) VALUES (35, 'template1'); 
INSERT INTO TEMPLATE_TRANSACTIONS (ID, NARRATION) VALUES (47, 'template2'); 
INSERT INTO ACCOUNTS (ID, NAME, PAYER_TEMPLATE_ID, CURRENCY_ID) VALUES (95, 'account0', null, 1); 
INSERT INTO ACCOUNTS (ID, NAME, PAYER_TEMPLATE_ID, CURRENCY_ID) VALUES (122, 'account1', 47, 0); 
INSERT INTO ACCOUNTS (ID, NAME, PAYER_TEMPLATE_ID, CURRENCY_ID) VALUES (178, 'foo bar', 35, 0); 
INSERT INTO TEMPLATE_TRANSACTION_LEGS (ID, HEAD_TABLE_ID, ACCOUNT_ID, AMOUNT) VALUES (23, 32, 95, null); 
INSERT INTO TEMPLATE_TRANSACTION_LEGS (ID, HEAD_TABLE_ID, ACCOUNT_ID, AMOUNT) VALUES (74, 35, 178, 500); 
INSERT INTO TEMPLATE_TRANSACTION_LEGS (ID, HEAD_TABLE_ID, ACCOUNT_ID, AMOUNT) VALUES (75, 35, null, -500); 

これは正常に動作してきましたプロダクションデータベースでしばらくの間、ブール値の列IS_PAYERをビューに追加する必要があります。のテンプレートトランザクションの場合はTRUEになります。上述したように、私は私が望むまさにんSELECT文を持っている:

HEAD_ID NARRATION LEG_ID ACCOUNT_ID AMOUNT CURRENCY_ID IS_PAYER 
--------------------------------------------------------------------------- 
32  template0 23  95   null  1    FALSE 
35  template1 74  178   500  0    TRUE 
35  template1 75  null   -500  null   TRUE 
47  template2 null  null   null  null   TRUE 

SELECT TEMPLATE_TRANSACTIONS.ID  AS HEAD_ID, 
    TEMPLATE_TRANSACTIONS.NARRATION, 
    TEMPLATE_TRANSACTION_LEGS.ID  AS LEG_ID, 
    TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID, 
    TEMPLATE_TRANSACTION_LEGS.AMOUNT, 
    ACCOUNTS.CURRENCY_ID, 
    IS_PAYER 
FROM (
    (TEMPLATE_TRANSACTIONS LEFT OUTER JOIN TEMPLATE_TRANSACTION_LEGS ON TEMPLATE_TRANSACTION_LEGS.HEAD_TABLE_ID = TEMPLATE_TRANSACTIONS.ID) 
    LEFT OUTER JOIN ACCOUNTS ON TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID = ACCOUNTS.ID) 
JOIN 
    (SELECT TEMPLATE_ID, (CASE WHEN PAYER_TEMPLATE_ID IS NOT NULL THEN TRUE ELSE FALSE END) AS IS_PAYER FROM 
     (SELECT TEMPLATE_TRANSACTIONS.ID AS TEMPLATE_ID, ACCOUNTS.PAYER_TEMPLATE_ID AS PAYER_TEMPLATE_ID FROM 
      ACCOUNTS RIGHT JOIN TEMPLATE_TRANSACTIONS ON ACCOUNTS.PAYER_TEMPLATE_ID =TEMPLATE_TRANSACTIONS.ID)) 
ON TEMPLATE_ID = TEMPLATE_TRANSACTIONS.ID 

が、私は次の操作を行います。その後、

DROP VIEW VIEW_TEMPLATES_DATA; 
CREATE VIEW VIEW_TEMPLATES_DATA AS (SELECT 
    TEMPLATE_TRANSACTIONS.ID  AS HEAD_ID, 
    TEMPLATE_TRANSACTIONS.NARRATION, 
    TEMPLATE_TRANSACTION_LEGS.ID  AS LEG_ID, 
    TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID, 
    TEMPLATE_TRANSACTION_LEGS.AMOUNT, 
    ACCOUNTS.CURRENCY_ID, 
    IS_PAYER 
FROM (
    (TEMPLATE_TRANSACTIONS LEFT OUTER JOIN TEMPLATE_TRANSACTION_LEGS ON TEMPLATE_TRANSACTION_LEGS.HEAD_TABLE_ID = TEMPLATE_TRANSACTIONS.ID) 
    LEFT OUTER JOIN ACCOUNTS ON TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID = ACCOUNTS.ID) 
JOIN 
    (SELECT TEMPLATE_ID, (CASE WHEN PAYER_TEMPLATE_ID IS NOT NULL THEN TRUE ELSE FALSE END) AS IS_PAYER FROM 
     (SELECT TEMPLATE_TRANSACTIONS.ID AS TEMPLATE_ID, ACCOUNTS.PAYER_TEMPLATE_ID AS PAYER_TEMPLATE_ID FROM 
      ACCOUNTS RIGHT JOIN TEMPLATE_TRANSACTIONS ON ACCOUNTS.PAYER_TEMPLATE_ID =TEMPLATE_TRANSACTIONS.ID)) 
ON TEMPLATE_ID = TEMPLATE_TRANSACTIONS.ID 
); 

SELECT * FROM VIEW_TEMPLATES_DATAを行くことがTEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID not found私に語りました。

私のオリジナルビューが受け入れられた理由は本当にわかりません。私の新しいSELECTもそうですが、私の新しいCREATE VIEWはありません!私はSQLでたくさんのことをしていないし、エラーメッセージは正確に役立つものではない、と私は本当にこれと一緒に行くべきか分からない。

どんな種類の人が私を解決の方向に向けることができますか?

+0

エラーメッセージを投稿してください。 –

+0

「SELECT * FROM VIEW_TEMPLATES_DATA'」と表示されます。h2は、「PUBLIC.VIEW_TEMPLATES_DATA」ビューが無効です。「列」「TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID」「not found [42122-167]」; SQL文: SELECT * FROM VIEW_TEMPLATES_DATA [90109-167] 90109/90109' – skiaddict1

答えて

3

問題は、JOIN句で使用しているカッコです。ビューのSELECTは、すぐにあなたがそれらを削除するように動作します:あなたは括弧の間の第1 LEFT OUTER JOINを置くとき

CREATE VIEW VIEW_TEMPLATES_DATA AS (SELECT 
    TEMPLATE_TRANSACTIONS.ID  AS HEAD_ID, 
    TEMPLATE_TRANSACTIONS.NARRATION, 
    TEMPLATE_TRANSACTION_LEGS.ID  AS LEG_ID, 
    TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID, 
    TEMPLATE_TRANSACTION_LEGS.AMOUNT, 
    ACCOUNTS.CURRENCY_ID, 
    IS_PAYER 
FROM TEMPLATE_TRANSACTIONS 
     LEFT OUTER JOIN TEMPLATE_TRANSACTION_LEGS ON TEMPLATE_TRANSACTION_LEGS.HEAD_TABLE_ID = TEMPLATE_TRANSACTIONS.ID 
     LEFT OUTER JOIN ACCOUNTS ON TEMPLATE_TRANSACTION_LEGS.ACCOUNT_ID = ACCOUNTS.ID 
     JOIN (SELECT TEMPLATE_ID, (CASE WHEN PAYER_TEMPLATE_ID IS NOT NULL THEN TRUE ELSE FALSE END) AS IS_PAYER 
       FROM (SELECT TEMPLATE_TRANSACTIONS.ID AS TEMPLATE_ID, ACCOUNTS.PAYER_TEMPLATE_ID AS PAYER_TEMPLATE_ID 
         FROM ACCOUNTS 
          RIGHT JOIN TEMPLATE_TRANSACTIONS ON ACCOUNTS.PAYER_TEMPLATE_ID =TEMPLATE_TRANSACTIONS.ID)) 
     ON TEMPLATE_ID = TEMPLATE_TRANSACTIONS.ID 
); 

を、結合されたテーブルTEMPLATE_TRANSACTION_LEGSは、第二LEFT OUTER JOINからは見えません。

+0

完璧!どうもありがとうございます!!私はこれを覚えていますが、明らかにそこに見えていない理由を理解できませんでしたが、今見ています。うんざりした説明もありがとう、もう一度ありがとう。 – skiaddict1

関連する問題