基本的多对多sql select查询

问题描述:

我认为这应该很容易,但它是在逃避我。我在帐户和帐户组之间建立了多对多的关系。一个帐户可以在零个或多个组中,所以我使用标准连接表。基本的多对多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

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。

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

SQL Server为此使用ISNULL()。我不确定这是否适用于Access。

是的,我将使用NULL的表示层。

但我必须错过一些东西。我碰到你同样的错误从我原来的尝试:

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

如何:

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 

这是否给你一个错误?可能更容易理解的错误?

我想在访问你可能想尝试这样的:

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 

我不知道为什么括号的事情,但我想与测试,它似乎解决它。

闯闯:

与两个外
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 

访问可能会遇到麻烦连接,因此我做了第二个内部连接应该工作

另一个想法...为什么不使用查询Access中的设计器。这应该需要大约30秒来设计“视图”。然后去看看它写的SQL。

不仅使用前面建议的查询设计器,还使用MS Access关系工具记录两个外键(AID,GID)和它们引用的主键之间的关系。

这使得在查询设计器中的自然连接几乎是儿童游戏。在您所描述的情况下,您甚至可以使用查询向导。

一旦你建立了查询,为什么不使用查询作为记录源而不是使用表?

我会在PHP中做的一件事就是将多个结果转换为逗号分隔列表。