问题
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
回答1:
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 n
th 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
回答2:
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);
回答3:
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
来源:https://stackoverflow.com/questions/20038812/join-two-tables-and-show-all-records-including-null