如何获得LEFT JOIN或FULL OUTER JOIN?

时间:2016-07-29 00:49:00

标签: ms-access

我有三张桌子:

客户表:

+------------------+------------+------------+
|     Customer     | Start Date |  End Date  |
+------------------+------------+------------+
| Cantrell, Beck   | 02/13/2016 | 12/22/2016 |
| Frazier, Urielle | 11/13/2015 | 01/03/2017 |
| Frost, Kato      | 05/27/2016 | 09/17/2016 |
| Larsen, Kuame    | 10/27/2015 | 08/09/2016 |
| Jennings, Echo   | 12/14/2015 | 03/09/2017 |
+------------------+------------+------------+

付款表:

+------------------+------------+------------+
|     Customer     |    Date    |   Amount   |
+------------------+------------+------------+
| Frost, Kato      | 05/27/2016 | 180.00     |
| Frost, Kato      | 06/06/2016 | 20.00      |
| Frost, Kato      | 06/07/2016 | 40.00      |
| Frost, Kato      | 06/13/2016 | 100.00     |
| Frost, Kato      | 06/20/2016 | 40.00      |
| Frost, Kato      | 06/27/2016 | 80.00      |
| Frost, Kato      | 07/05/2016 | 60.00      |
| Frost, Kato      | 07/12/2016 | 40.00      |
+------------------+------------+------------+

我还有第三张表Dates,这只是从2010年1月1日到1月20日的日期列表。

客户应在每周开始日期当天到期。为了获得整个项目的每个客户的费用清单,我创建了以下查询:

SELECT Dates.Date, 
IIf([Dates].[date]=[Customers].[Start Date],177,77) AS Accrued
FROM Customers, Dates
WHERE (((Customers.[Start Date])<=[date]) 
     And ((Customers.[End Date])>=[date]) 
     AND ((Weekday(Dates.date))=Weekday(Customers.[Start Date])) 
     And ((Customers.Customer)=[Which Customer?]));

生成此结果:

+--------------------+--------------------+
|        Date        |      Accrued       |
+--------------------+--------------------+
|          5/27/2016 |                177 |
|           6/3/2016 |                 77 |
|          6/10/2016 |                 77 |
|          6/17/2016 |                 77 |
|          6/24/2016 |                 77 |
|           7/1/2016 |                 77 |
|           7/8/2016 |                 77 |
|          7/15/2016 |                 77 |
|          7/22/2016 |                 77 |
|          7/29/2016 |                 77 |
|           8/5/2016 |                 77 |
|          8/12/2016 |                 77 |
|          8/19/2016 |                 77 |
|          8/26/2016 |                 77 |
|           9/2/2016 |                 77 |
|           9/9/2016 |                 77 |
|          9/16/2016 |                 77 |
+--------------------+--------------------+

现在,我需要添加所有当前付款,因此我添加了付款表。

[按客户收费]查询:

SELECT Dates.Date, 
       IIf([Dates].[date]=[Customers].[Start Date],177,77) AS Accrued,
       Payments.Date, 
       Payments.Amount
FROM Dates, 
     Customers INNER JOIN Payments ON Customers.Customer = Payments.Customer
WHERE (((Customers.[Start Date])<=[Dates].[date]) 
  AND ((Customers.[End Date])>=[Dates].[date]) 
  AND ((Weekday([Dates].[date]))=Weekday([Customers].[Start Date])) 
  AND ((Customers.Customer)=[Which Customer?]));

结果是每笔付款重复的每份应计的清单。我想调整JOIN以查看是否可以将Accrued限制为仅一次,但每次我尝试时,都会收到错误消息,指出存在模糊的外连接。

相反,我尝试将它分成两个查询,然后将它们连接在一起。

[客户付款]查询:

SELECT Payments.Date, Payments.Amount, Customers.Customer
FROM Customers LEFT JOIN Payments ON Customers.Customer = Payments.Customer
WHERE (((Customers.Customer)=[Which Customer?]));

产生以下结果:

+--------------------+--------------------+
|        Date        |       Amount       |
+--------------------+--------------------+
|         05/27/2016 |             180.00 |
|         06/06/2016 |              20.00 |
|         06/07/2016 |              40.00 |
|         06/13/2016 |             100.00 |
|         06/20/2016 |              40.00 |
|         06/27/2016 |              80.00 |
|         07/05/2016 |              60.00 |
|         07/12/2016 |              40.00 |
+--------------------+--------------------+

然后我尝试了一个完整的外部联接,但在阅读之后,似乎Access不支持它们。我找到了一些使用UNIONS绕过它的例子。

SELECT [Charges by Customer].Date, [Charges by Customer].Accrued, [Payments by Customer].Date, [Payments by Customer].Amount
    FROM [Charges by Customer] LEFT JOIN [Payments by Customer] ON [Charges by Customer].Customer = [Payments by Customer].Customer
UNION
SELECT [Payments by Customer].Date, [Payments by Customer].Amount, [Payments by Customer].Date, [Payments by Customer].Amount
    FROM [Payments by Customer] LEFT JOIN [Charges by Customer] ON [Payments by Customer].Customer = [Charges by Customer].Customer

在摆弄了一段时间后,我很困惑,不知道该在哪里继续。 Access有点丢失了。我对MySQL更熟悉,而且差异(和UI)使我很难围绕我需要做的事情来获得我想要的结果。

我理想的结果是这样的:

+-----------+---------+------------+--------+
| Date      | Accrued |    Date    | Amount |
+-----------+---------+------------+--------+
| 5/27/2016 |     177 | 05/27/2016 | 180.00 |
|  6/3/2016 |      77 |            |        |
|           |         | 06/06/2016 |  20.00 |
|           |         | 06/07/2016 |  40.00 |
| 6/10/2016 |      77 |            |        |
|           |         | 06/13/2016 | 100.00 |
| 6/17/2016 |      77 |            |        |
|           |         | 06/20/2016 |  40.00 |
| 6/24/2016 |      77 |            |        |
|           |         | 06/27/2016 |  80.00 |
|  7/1/2016 |      77 |            |        |
|           |         | 07/05/2016 |  60.00 |
|  7/8/2016 |      77 |            |        |
|           |         | 07/12/2016 |  40.00 |
| 7/15/2016 |      77 |            |        |
| 7/22/2016 |      77 |            |        |
| 7/29/2016 |      77 |            |        |
|  8/5/2016 |      77 |            |        |
| 8/12/2016 |      77 |            |        |
| 8/19/2016 |      77 |            |        |
| 8/26/2016 |      77 |            |        |
|  9/2/2016 |      77 |            |        |
|  9/9/2016 |      77 |            |        |
| 9/16/2016 |      77 |            |        |
+-----------+---------+------------+--------+

如果您有任何想法或解决方案,我将非常感激。谢谢!

1 个答案:

答案 0 :(得分:0)

您的方法存在一些问题

  1. [客户收费]查询缺少列Customer
  2. [客户收费]

    SELECT Customers.Customer, 
           Dates.Date, 
           IIf([Dates].[date]=[Customers].[Start Date],177,77) AS Accrued
    FROM Customers, Dates
    WHERE (((Customers.[Start Date])<=[date]) 
         And ((Customers.[End Date])>=[date]) 
         AND ((Weekday([Dates].[date]))=Weekday([Customers].[Start Date]))  
         And ((Customers.Customer)='Frost, Kato'))
    
    1. 你需要一个Right of Right Join和Left Join,然后按日期排序,以获得你的最终结果:
    2. SELECT a.Customer, a.Date1, a.Accrued, a.Date2, a.Amount FROM ( select NZ(C.Customer,P.Customer) as Customer, NZ(C.Date, P.Date) as Date1, C.Accrued, P.Amount, P.Date as Date2 from [Charges by Customer] C RIGHT OUTER JOIN [Payments by Customer] P ON C.Customer = P.Customer and P.Date = C.Date UNION select C.Customer, C.Date, C.Accrued, P.Amount, P.Date as Date2 from
      [Charges by Customer] C LEFT OUTER JOIN [Payments by Customer] P ON C.Customer = P.Customer and P.Date = C.Date ) a Order by Date1

      1. 此外,您的带有Union的查询缺少按日期(and P.Date = C.Date)加入的连接条件。您只能加入[Charges by Customer].Customer and [Payments by Customer].Customer
      2. 中的客户列

        如果您需要任何澄清,请告诉我。