2009-01-23 127 views
0

我認爲這應該很容易,但它是在逃避我。我在帳戶和帳戶組之間建立了多對多的關係。一個帳戶可以在零個或多個組中,所以我使用標準連接表。基本的多對多sql select查詢

Accounts 
-------- 
ID 
BankName 
AcctNumber 
Balance 

AccountGroups 
------------- 
ID 
GroupName 

JoinAccountsGroups 
------------------ 
AID 
GID 

我正在使用MS Access,FWIW。此外,這是針對低帶寬的情況,所以代碼優化不像簡單/可讀性那麼重要。

我使用php作爲表示層,所以Access的一個簡單的結果是好的。

至於如何處理多重結果的情況,我實際上有兩件事情正在嘗試構建。首先列出所有組在一列這樣的:

Bank  AcctNum  Balance Groups 
--------|--------------|----------|---------------- 
Citi  930938  400  Payroll 
HSBC  8372933  100  Monthly, Payroll 
Wells  09837   800  - 
Chase  8730923  250  Monthly 

第二個是主詳細列表:

Name   AcctNum Balance 
------------|----------|---------- 
Payroll (2)    500 
    Citi  930938  400 
    HSBC  8372933 100   
.................................. 
Monthly (2)    350 
    HSBC  8372933 100   
    Chase  8730923 250 
.................................. 
Wells   09837  800 

對於主從,我的計劃只是爲了得到一個大的結果集從數據庫,並根據需要在PHP中夯實它。既然在php中會有一些重要的後處理,也許我應該只做三個單獨的查詢,然後在那裏進行加入。 (因爲我更熟悉該語言。)

+0

您的數據很混亂,因爲您有多對多的加入,當有一個或兩個以上的組與帳戶關聯時,您會發生什麼?您的輸出顯示每個帳戶一行? – AnthonyWJones 2009-01-23 16:53:24

+0

您沒有使用Access - 您正在使用Jet MDB作爲數據存儲。 – 2009-01-25 01:07:15

+0

「你沒有使用Access」:你怎麼知道他們沒有使用MS Access來寫Jet語法的SQL(你也這樣做)?你怎麼知道他們沒有使用Access 2007的ACE,'A'代表'Access'? – onedaywhen 2009-01-26 10:04:47

回答

1

SELECT a.BankName, a.AcctNumber, a.Balance, ag.GroupName 
FROM (Accounts a 
     LEFT JOIN JoinAccountsGroups jag 
     ON a.ID = jag.AID) 
     LEFT JOIN AccountGroups ag 
     ON jag.GID = ag.GroupName; 

會選擇第一個表中的數據,但是以連接組(每月,工資),你需要一個用戶定義函數(UDF),至極將無法使用到Jet ,所以在PHP中處理將是必要的。您可能希望閱讀Understanding SQL Joins。它指的是MySQL,但大部分適用於Jet。

0
SELECT act.acctid AS AcctId, bankName, acctNumber, Balance, 
     NVL(jag.gid, '-') AS GroupID, NVL(gp.groupname, '-') AS GroupName 
FROM accounts act 
    LEFT OUTER JOIN JointAccountGroups jag ON (act.id = jag.aid) 
    LEFT OUTER JOIN AccounGroups gp ON (jag.gid = gp.id) 

NVL是一個函數,它的意思是「如果第一個參數爲null,則返回第二個參數;否則,返回的第一個參數」。 NVL恰好是Oracle如何做的 - 所有DB都有類似的東西,但它沒有標準名稱;請看看Access如何做到這一點。

+0

或者將null留在原來的位置,並在表示層中將其顯示爲' - '。 – bobince 2009-01-23 16:56:43

+0

當然:-)。我不知道他*是否有*表示層,所以我爲了完整性而拋棄了它。但是,如果一個人能夠實現表示和數據的分離,那麼你應該是正確的。 – SquareCog 2009-01-23 16:58:31

+0

NVL可能與T-SQL中的COALESCE類似,我不是Oracle人。 – BuddyJoe 2009-01-23 17:08:56

0

SQL Server爲此使用ISNULL()。我不確定這是否適用於Access。

0

是的,我將使用NULL的表示層。

但我必須錯過一些東西。我碰到你同樣的錯誤從我原來的嘗試:

Syntax error (missing operator) in query expression '(act.id = jag.aid) 
        LEFT OUTER JOIN accountgroups gp ON (jag.gid = gp.id)' 
0

如何:

SELECT act.acctid AS AcctId, bankName, acctNumber, Balance, 
     jag.gid AS GroupID, gp.groupname AS GroupName 
FROM accounts AS act 
    LEFT OUTER JOIN JointAccountGroups AS jag ON act.id = jag.aid 
    LEFT OUTER JOIN AccounGroups AS gp ON jag.gid = gp.id 

這是否給你一個錯誤?可能更容易理解的錯誤?

0

我想在訪問你可能想嘗試這樣的:

FROM (accounts AS act 
    LEFT OUTER JOIN JointAccountGroups AS jag ON act.id = jag.aid) 
    LEFT OUTER JOIN AccounGroups AS gp ON jag.gid = gp.id 

我不知道爲什麼括號的事情,但我想與測試,它似乎解決它。

0

闖闖:

與兩個外
SELECT act.acctid AS AcctId, bankName, acctNumber, Balance, 
    jag.gid AS GroupID, gp.groupname AS GroupName 
FROM accounts AS act 
    LEFT OUTER JOIN JointAccountGroups AS jag ON act.id = jag.aid 
    LEFT INNER JOIN AccounGroups AS gp ON jag.gid = gp.id 

訪問可能會遇到麻煩連接,因此我做了第二個內部連接應該工作

1

另一個想法...爲什麼不使用查詢Access中的設計器。這應該需要大約30秒來設計「視圖」。然後去看看它寫的SQL。

0

不僅使用前面建議的查詢設計器,還使用MS Access關係工具記錄兩個外鍵(AID,GID)和它們引用的主鍵之間的關係。

這使得在查詢設計器中的自然連接幾乎是兒童遊戲。在您所描述的情況下,您甚至可以使用查詢嚮導。

一旦你建立了查詢,爲什麼不使用查詢作爲記錄源而不是使用表?

我會在PHP中做的一件事就是將多個結果轉換爲逗號分隔列表。