Question

I have two tables in Microsoft Access 2013:

tblService

ID PART_ID SERV_DATE SERV_REMARK
1   A0001  11/1/2013   GOOD#1
2   A0001  11/13/2013  GOOD#2
3   A0001  11/25/2013  GOOD#3
4   B0001  11/26/2013  GOOD#4
5   C0001  12/1/2013   GOOD#5
6   C0001  12/10/2013  GOOD#6
7   C0001  12/20/2013  GOOD#7

tblWithdraw

ID PART_ID DRAWN_DATE DRAWN_REASON DRAWN_TO
1   A0001  11/6/2013       PM        OW601
2   A0001  11/20/2013    120 PM      OW603
3   A0001  11/30/2013  REPLACEMENT   OW605 
4   C0001  12/2/2013      30 PM      OW701
5   C0001  12/15/2013    180 PM      OW702

I'd like to join the two tables to have the result as shown below:

PART_ID SERV_DATE SERV_REMARK DRAWN_DATE DRAWN_REASON DRAWN_TO
 A0001  11/1/2013   GOOD#1    11/6/2013       PM        OW601
 A0001  11/13/2013  GOOD#2    11/20/2013    120 PM      OW603
 A0001  11/25/2013  GOOD#3    11/30/2013  REPLACEMENT   OW605
 B0001  11/26/2013  GOOD#4
 C0001  12/1/2013   GOOD#5    12/2/2013       PM        OW701
 C0001  12/10/2013  GOOD#6    12/15/2013    180 PM      OW702
 C0001  12/20/2013  GOOD#7

I have been working for weeks but still unable to get the result. Can somebody show me the Query? Thanks a lot!

Edited Nov18 1035:

I have tried:

SELECT s.PART_ID, s.SERV_DATE, s.SERV_REMARK,
w.DRAWN_DATE, w.DRAWN_REASON, w.DRAWN_TO
FROM tblService AS s
LEFT JOIN tblWithdraw AS w
ON s.PART_ID = w.PART_ID

Result was:

PART_ID SERV_DATE   SERV_REMARK DRAWN_DATE  DRAWN_REASON    DRAWN_TO
 A0001  11/1/2013     GOOD #1   11/6/2013        PM           OW601
 A0001  11/1/2013     GOOD #1   11/20/2013     120 PM         OW602
 A0001  11/1/2013     GOOD #1   11/30/2013  REPLACEMENT       OW603
 A0001  11/13/2013    GOOD #2   11/6/2013        PM           OW601
 A0001  11/13/2013    GOOD #2   11/20/2013     120 PM         OW602
 A0001  11/13/2013    GOOD #2   11/30/2013  REPLACEMENT       OW603
 A0001  11/25/2013    GOOD #3   11/6/2013        PM           OW601
 A0001  11/25/2013    GOOD #3   11/20/2013     120 PM         OW602
 A0001  11/25/2013    GOOD #3   11/30/2013  REPLACEMENT       OW603
 B0001  11/26/2013    GOOD #4           
 C0001  12/1/2013     GOOD #5   12/2/2013        PM           OW701
 C0001  12/1/2013     GOOD #5   12/15/2013     180 PM         OW702
 C0001  12/10/2013    GOOD #6   12/2/2013        PM           OW701
 C0001  12/10/2013    GOOD #6   12/15/2013     180 PM         OW702
 C0001  12/20/2013    GOOD #7   12/2/2013        PM           OW701
 C0001  12/20/2013    GOOD #7   12/15/2013     180 PM         OW702
Was it helpful?

Solution

I originally thought that the following would work for you:

SELECT s.PART_ID, s.SERV_DATE, s.SERV_REMARK, 
  w.DRAWN_DATE, w.DRAWN_REASON, w.DRAWN_TO
FROM tblService AS s
  LEFT JOIN tblWithdraw AS w
  ON s.PART_ID = w.PART_ID

However that would not work since part ID is not unique in the tblService table. So then I started looking for a date field that matched in the two tables. The date fields do not match.

So, based on what you are showing here you have no way of linking the two tables together.

Your output looks like you want to iterate through the tblService table and then find a matching record in the tblWithdraw table and match them together. Then if there is a second record with the same PART_ID in the tblService table, match it with the second occurrence of the same PART_ID in the tblWithdraw table. Then repeat this as many times as it takes. If there isn't a matching record in tblWithdraw that matches the nth occurrence in tblService then output the information found in tblService anyway.

You cannot perform such a convoluted query in SQL. If you really want to do this, you could use code like VBA, C# and/or etc to iterate through the tblService and then iterate through tblWithdraw to find what you are looking for.

A better alternative: If the tables you are showing only contains the fields you are showing, then you need to modify the tables and add a unique primary key field to tblService. Then add a foreign key in the tblWithdraw table matching the primary key of tblService.

Then the following would work:

SELECT s.PART_ID, s.SERV_DATE, s.SERV_REMARK, 
  w.DRAWN_DATE, w.DRAWN_REASON, w.DRAWN_TO
FROM tblService AS s
  LEFT JOIN tblWithdraw AS w
  ON s.tblServiceID = w.tblServiceID 

OTHER TIPS

Use a correlated subquery to get the next DRAWN_DATE for each combination of PART_ID and SERV_DATE. Using your sample data in Access 2007, this is the output from the following query.

PART_ID SERV_DATE  SERV_REMARK next_drawn_date
A0001    11/1/2013 GOOD#1            11/6/2013
A0001   11/13/2013 GOOD#2           11/20/2013
A0001   11/25/2013 GOOD#3           11/30/2013
B0001   11/26/2013 GOOD#4 
C0001    12/1/2013 GOOD#5            12/2/2013
C0001   12/10/2013 GOOD#6           12/15/2013
C0001   12/20/2013 GOOD#7 

SELECT
    s.PART_ID,
    s.SERV_DATE,
    s.SERV_REMARK,
    (
        SELECT Min(DRAWN_DATE)
        FROM tblWithDraw
        WHERE
                PART_ID = s.PART_ID
            AND DRAWN_DATE >= s.SERV_DATE
    ) AS next_drawn_date
FROM tblService AS s;

Then you can use that as a subquery and join it to tblWithdraw.

SELECT
    sub.PART_ID,
    sub.SERV_DATE,
    sub.SERV_REMARK,
    sub.next_drawn_date AS DRAWN_DATE,
    w.DRAWN_REASON,
    w.DRAWN_TO
FROM
    (
        SELECT
            s.PART_ID,
            s.SERV_DATE,
            s.SERV_REMARK,
            (
                SELECT Min(DRAWN_DATE)
                FROM tblWithDraw
                WHERE
                        PART_ID = s.PART_ID
                    AND DRAWN_DATE >= s.SERV_DATE
            ) AS next_drawn_date
        FROM tblService AS s
    ) AS sub
    LEFT JOIN tblWithdraw AS w
    ON
            (sub.PART_ID = w.PART_ID)
        AND (sub.next_drawn_date = w.DRAWN_DATE);

SELECT s.PART_ID, s.SERV_DATE, s.SERV_REMARK, w.DRAWN_DATE, w.DRAWN_REASON, w.DRAWN_TO FROM tblService AS s LEFT JOIN tblWithdraw AS w ON s.tblServiceID = w."TWLWITHDRAW" -- small correction

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top