Sql 但是B.ID=2和B.ID=3在结果中都出现了两次。我希望每个B.ID在结果集中的任何位置都不超过一次。@JoelCoehoorn,你认为这可以在子选择中完成吗?我一直觉得子选择将没有从B中选择记录的范围。这感觉像是一种必须的方法。谢谢,但不幸的是,这对结
Sql 但是B.ID=2和B.ID=3在结果中都出现了两次。我希望每个B.ID在结果集中的任何位置都不超过一次。@JoelCoehoorn,你认为这可以在子选择中完成吗?我一直觉得子选择将没有从B中选择记录的范围。这感觉像是一种必须的方法。谢谢,但不幸的是,这对结,sql,left-join,Sql,Left Join,但是B.ID=2和B.ID=3在结果中都出现了两次。我希望每个B.ID在结果集中的任何位置都不超过一次。@JoelCoehoorn,你认为这可以在子选择中完成吗?我一直觉得子选择将没有从B中选择记录的范围。这感觉像是一种必须的方法。谢谢,但不幸的是,这对结果集没有影响。如果DISTINCT修饰符作用于整个元组,那么每个元组都已经不同了。我认为这只作用于第一列。试试看。我用selectdistinct(B.ID),…试过了,结果还是没有改变。我使用MS Access进行测试,但我不认为这有什么区别
但是
B.ID=2
和B.ID=3
在结果中都出现了两次。我希望每个B.ID在结果集中的任何位置都不超过一次。@JoelCoehoorn,你认为这可以在子选择中完成吗?我一直觉得子选择将没有从B中选择记录的范围。这感觉像是一种必须的方法。谢谢,但不幸的是,这对结果集没有影响。如果DISTINCT
修饰符作用于整个元组,那么每个元组都已经不同了。我认为这只作用于第一列。试试看。我用selectdistinct(B.ID),…
试过了,结果还是没有改变。我使用MS Access进行测试,但我不认为这有什么区别。谢谢,但不幸的是,这对结果集没有影响。如果DISTINCT
修饰符作用于整个元组,那么每个元组都已经不同了。我认为这只作用于第一列。试试看。我用selectdistinct(B.ID),…
试过了,结果还是没有改变。我使用MS Access进行测试,但我不认为这有什么区别。哦,我没有意识到你(一小时前)编写了与我几乎完全相同的查询。不过我们有区别,你在子查询中按a.id
分组,我使用b.id
。我认为结果会稍有不同。@ypercube您可能正在删除多个A
记录,IMHO,如果两个B
记录匹配相同的A
记录,您仍然会有包含多个B
记录的输出。我现在正在处理这个问题。它不能像复制/粘贴那样工作,但这绝对是一个很好的开始。谢谢你,我会告诉你结果如何。@haventcheck我刚意识到MS Access不喜欢那样的多个左连接。我不喜欢它,但试着像这样格式化它问:哦,我没意识到你(一小时前)写的几乎和我完全一样的查询。不过我们有一个区别,你按a.id
分组,在子查询中,我使用b.id
。我认为结果会稍有不同。@ypercube您可能正在删除多个A
记录,IMHO,如果两个B
记录匹配相同的A
记录,您仍然会有包含多个B
记录的输出。我现在正在处理这个问题。它不能像复制/粘贴那样工作,但这绝对是一个很好的开始。谢谢你,我会告诉你结果如何。@haventcheck我刚意识到MS Access不喜欢那样的多个左连接。我没有小提琴,但是试着像下面这样格式化它:谢谢你这么辛苦的工作。今晚晚些时候,我将对此进行深入研究,并将与大家讨论结果。感谢大家的辛勤工作。今晚晚些时候,我将对此进行深入研究,并将与您联系,了解其工作原理。谢谢您。我会深入调查一下,然后再打给你。非常感谢:)谢谢你。我会深入调查一下,然后再打给你。非常感谢:)
Table A
ID AGE EDUCATION
1 23 3
2 25 6
3 22 5
Table B
ID AGE EDUCATION
1 26 4
2 24 6
3 21 3
SELECT *
FROM TableA as A LEFT JOIN TableB as B ON
abs(A.age - B.age) <= 2 AND
abs(A.education - B.education) <= 2
A.ID A.AGE A.EDUCATION B.ID B.AGE B.EDUCATION
1 23 3 3 21 3
2 25 6 1 26 4
2 25 6 2 24 6
3 22 5 2 24 6
3 22 5 3 21 3
A.ID A.AGE A.EDUCATION B.ID B.AGE B.EDUCATION
1 23 3 3 21 3
2 25 6 1 26 4
2 25 6 2 24 6
3 22 5 null null null
DECLARE @JoinResults TABLE
(A_ID INT, A_Age INT, A_Education INT, B_ID INT, B_Age INT, B_Education INT)
INSERT INTO @JoinResults (A_ID, A_Age, A_Education)
SELECT ID, AGE, EDUCATION
FROM TableA
DECLARE @i INT
SET @i = 1
--Assume that A_ID is incremental and no values missed
WHILE (@i < (SELECT Max(A_ID) FROM @JoinResults
BEGIN
UPDATE @JoinResult
SET B_ID = SQ.ID,
B_Age = SQ.AGE,
B_Education = SQ.Education
FROM (
SELECT ID, AGE, EDUCATION
FROM TableB b
WHERE (
abs((SELECT A_Age FROM @JoinResult WHERE A_Id = @i) - AGE) <=2
AND abs((SELECT A_Education FROM @JoinResult WHERE A_Id = @i) - EDUCATION) <=2
) AND (SELECT B_ID FROM @JoinResults WHERE B_ID = b.id) IS NULL
) AS SQ
SET @i = @i + 1
END
SELECT @JoinResults
select a.id a_id, a.age a_age, a.education a_e,
b.id b_id, b.age b_age, b.education b_e
from a left join
(
SELECT
a.id a_id, min(b.id) b_id from a,b where
abs(A.age - B.age) <= 2 AND
abs(A.education - B.education) <= 2
group by a.id
) g on a.id = g.a_id
left join b on b.id = g.b_id;
SELECT
a.id, a.age, a.education,
b.id AS b_id, b.age AS b_age, b.education AS b_education
FROM tableB AS b
CROSS APPLY
( SELECT TOP (1) a.*
FROM tableA AS a
WHERE ABS(a.age - b.age) <= 2
AND ABS(a.education - b.education) <= 2
ORDER BY a.id -- your choice here
) AS a ;
SELECT
a.id, a.age, a.education,
s.id AS s_id, s.age AS b_age, s.education AS b_education
FROM tableB AS a
LEFT JOIN
( SELECT
b.id, b.age, b.education, MIN(a.id) AS a_id
FROM tableB AS b
JOIN tableA AS a
ON ABS(a.age - b.age) <= 2
AND ABS(a.education - b.education) <= 2
GROUP BY b.id, b.age, b.education
) AS s
ON a.id = s.a_id ;