2011-08-03 70 views
2

我需要做的完全相同的东西,如下所示:INNER or LEFT Joining Multiple Table Records Into A Single Row但它有一个MS Access查询。MS Access外部加入多个字段到单个记录

下面是场景:


电话表

+----------------+-------------+ 
| Field   | Type  | 
+----------------+-------------+ 
| f_id   | int(15)  | 
| f_client_id | int(11)  | 
| f_phone_type | varchar(50) | 
| f_phone_number | varchar(13) | 
+----------------+-------------+ 

客户表

+-----------------------------+--------------+------+-----+ 
| Field      | Type   | Null | Key | 
+-----------------------------+--------------+------+-----+ 
| f_id      | int(15)  | NO | PRI | 
| f_first_name    | varchar(13) | YES | MUL | 
| f_mi      | char(1)  | YES |  | 
| f_last_name     | varchar(20) | NO | MUL | 
+-----------------------------+--------------+------+-----+ 

使用标准LEFT或INNER JOIN ,我得到的是这样的:

+------------+------------+--------------+ 
| name  | Phone Type | Phone Number | 
+------------+------------+--------------+ 
| John Smith | Home  | 712-555-6987 | 
| John Smith | Work  | 712-555-1236 | 
+------------+------------+--------------+ 

我需要一个查询,这将使我属于一个给定的客户端的工作和家庭数字:

+------------+----------------+--------------+ 
| Name  | Work Number | Home Number | 
+------------+----------------+--------------+ 
| John Smith | 712-555-1236 | 712-555-6987 | 
+------------+----------------+--------------+ 

解决方案在SQL中是

SELECT CONCAT(c.f_first_name, ' ', c.f_last_name) as Client_Name, 
     wp.f_phone_number as Work_Number, 
     hp.f_phone_number as Home_Number 

    FROM clients c 
     LEFT OUTER JOIN phone hp 
     ON hp.f_client_id = c.f_id 
    AND 
     hp.phone_type = 'home' 
     LEFT OUTER JOIN phone wp 
     ON wp.f_client_id = c.f_id 
    AND 
     wp.phone_type = 'work' 

但是这并没有转化为MS Access,连接失败。通过Access完成同样的事情的最好方法是什么?

回答

5

您还没有发现两个问题。

  1. 没有在Access没有CONCAT()函数或其数据库引擎
  2. 查询尝试使用PHONE_TYPE,但实际的字段名称是f_phone_type

当加入两个以上的表,访问'数据库引擎需要括号。通过使用查询设计器来设置连接最容易。此外查询设计器将用LEFT JOIN替代LEFT OUTER JOIN;无论哪种方式在Access 2003中都适用。

这个在查询设计器中很容易构建,但只返回具有家庭和工作号码的客户的行。我用它作为起点,然后调整与您的原始类似的ON子句。

SELECT 
    c.f_first_name & " " & c.f_last_name AS [Name], 
    wp.f_phone_number AS [Work Number], 
    hp.f_phone_number AS [Home Number] 
FROM 
    (Clients AS c 
    LEFT JOIN Phones AS hp 
    ON c.f_id = hp.f_client_id) 
    LEFT JOIN Phones AS wp 
    ON c.f_id = wp.f_client_id 
WHERE 
    hp.f_phone_type='Home' 
    AND wp.f_phone_type='Work'; 

移动那些条件为ON表达式,如您的SQL Server实例,将您是否没有对文件进行他们的任何电话号码返回所有客户。但是,这种方法需要围绕ON表达式使用括​​号。并且这些JOINS不能显示在查询设计器中。

SELECT 
    c.f_first_name & " " & c.f_last_name AS [Name], 
    wp.f_phone_number AS [Work Number], 
    hp.f_phone_number AS [Home Number] 
FROM 
    (Clients AS c 
    LEFT JOIN Phones AS hp 
    ON (c.f_id = hp.f_client_id AND hp.f_phone_type='Home')) 
    LEFT JOIN Phones AS wp 
    ON (c.f_id = wp.f_client_id AND wp.f_phone_type='Work'); 

更新:至于我自己,我宁愿用子查询做到这一点。

SELECT 
    c.f_first_name & " " & c.f_last_name AS [Name], 
    wp.f_phone_number AS [Work Number], 
    hp.f_phone_number AS [Home Number] 
FROM 
    (Clients AS c 
    LEFT JOIN [ 
     SELECT f_client_id, f_phone_number 
     FROM Phones 
     WHERE f_phone_type='Home' 
    ]. AS hp 
    ON c.f_id = hp.f_client_id) 
    LEFT JOIN [ 
     SELECT f_client_id, f_phone_number 
     FROM Phones 
     WHERE f_phone_type='Work' 
    ]. AS wp 
    ON c.f_id = wp.f_client_id; 
+0

真棒,正是我需要的!我发现WHERE子句方法只返回两个电话号码的行,我甚至需要显示空白数字,所以我使用了第一种方法。我也切换到左外部连接,以确保所有记录被返回,它似乎在Access 2010中正常工作。 再次感谢! –

+0

对,我在WHERE子句中犯了一个错误,它违背了LEFT JOIN的目的。另外,我对左外连接和左连接感到困惑。引擎确实接受LEFT OUTER JOIN,查询设计器将其转换为LEFT JOIN。我编辑了解决这些问题的答案,并添加了子查询方法。 – HansUp

+0

在Jet/ACE的SQL方言中,LEFT OUTER JOIN是LEFT JOIN的同义词。我很确定它也适用于所有其他SQL方言。您可以键入额外的单词,但如果保存查询,Jet/ACE会将其删除并留下LEFT JOIN,因此根本无法输入。 –

0

您还可以使用子查询,如:

SELECT (firstname & " " & lastname) AS fullname, 
    (SELECT f_PhoneNumber FROM tblPhones 
    WHERE f_clientID = clients.id AND f_PhoneType = "Home") 
    AS HomeNumber, 
    (SELECT f_PhoneNumber FROM tblPhones 
    WHERE f_clientID = clients.id AND f_PhoneType = "Work") 
    AS WorkNumber 
FROM clients 
+0

感谢Albert,我很感谢提示!我用其他方法发布了。我不确定这两种方法是否存在性能差异,但是有些东西让我害怕选择内部的选择......可能完全没有根据!我确信两个答案都会给出预期的结果。 –

+0

我可能也会加入。但是,上述语法适用于sql server,可能适用于MySql。通常编写这样的子查询更容易编写,并且它可能只是一个简单的子查询在JET sql中可用,并且他们通常可以从中得到一个。 –

+0

子查询还可以帮助编辑... –

相关问题