[英]Finding closest value in another table
我对 SQL 很陌生,所以对我来说很陌生。 我想要做的是为每条记录返回最接近不同表中另一个值的值。
我将展示我的两个表格的简化示例以进行说明
第一个表是我希望值 ENTRY_YEAR 匹配的表:
ID | ENTRY_VALUE |
---|---|
1001 | 1900 |
1002 | 2000 |
第二张桌子:
ID | ENTRY_VALUE | 状态 |
---|---|---|
1001 | 1880年 | 成功 |
1001 | 1930年 | 失败 |
1001 | 1940 | 成功 |
1002 | 1960 | 成功 |
1002 | 1980 | 失败 |
所以我要寻找的最终结果是:
ID | ENTRY_VALUE | 状态 |
---|---|---|
1001 | 1880年 | 成功 |
1002 | 1980 | 失败 |
我目前只设法将 id 链接在一起,但找不到一种方法来比较两个表中的 ENTRY_VALUE 并返回最接近 Table1 条目的那个。
所以只有这个:
SELECT * from Table2
INNER JOIN Table1 ON (Table2.ID = Table1.ID)
我再一次对基本问题不好,我用谷歌搜索了所有内容,但无法正常工作,所以非常欢迎任何帮助!
这是一个(执行速度较慢的)查询。 第一次尝试。 这是一种使用“相关子查询”的方法,因此它为外部查询的每一行运行内部查询,该策略是为每一行确定我们正在寻找的最小值。 然后 select 只有符合该条件的行,但此类查询在运行时可能会很慢。 虽然逻辑很干净。
select
a.id,
b.entry_value,
b.[status]
from
Foo a
inner join Bar b
on a.id = b.id
where
abs(a.entry_value - b.entry_value) =
(select min(abs(t1.entry_value-t2.entry_value))
from Foo t1
inner join Bar t2
on t1.id = t2.id
where
t1.id = a.id
group by t1.id)
如果您有很多行(数以万计,或者在任何情况下如果前一个查询太慢),那么下一个应该会更好地执行。 第二次尝试,如果您自己运行两个内部查询。 您可能会在这里看到我们如何加入他们以获得预期结果的策略。
select A.Id, A.entry_value, A.[status]
from
(
select t1.id, t2.entry_value, abs(t1.entry_value-t2.entry_value) as diff, t2.[status]
from Foo t1
inner join Bar t2
on t1.id = t2.id
) A
inner join
(
select t3.id, min(abs(t3.entry_value-t4.entry_value)) as diff
from Foo t3
inner join Bar t4
on t3.id = t4.id
group by t3.id
) B
on A.id = B.id
and A.diff = B.diff
我可能不会尝试在 MSAccess 的“设计视图”中编写这些查询中的任何一个,但如果我也这样做的话,我相信我可以。 但通常,在这种情况下,我会“手动”编写查询并使用 MSAccess“SQL 视图”将其直接粘贴到您的查询中。
请注意,平局会导致两行:示例:第一个表有(1003,2000)
第二个表有(1003, 1990, 'success')
和(1003, 2010, 'fail')
你将得到一个包含两行的结果,一个success
,另一个fail
(!)
所以你真的应该测试你的数据并寻找可能产生这种联系的情况(并在必要时决定做什么)。
只是为了好玩,以下是您在 SQL 服务器中可能 go 的方式。 但不幸的是,我认为这在 MSAccess 中不起作用。
select
T.id,
T.entry_value,
T.[status]
from
(
select
t1.id,
t2.entry_value,
abs(t1.entry_value-t2.entry_value) as diff,
t2.[status],
rank() over (partition by t1.id order by abs(t1.entry_value-t2.entry_value)) as seq
from #Foo t1
inner join #Bar t2
on t1.id = t2.id
) T
where T.seq = 1;
使用简单的子查询来查找最小偏移量:
Select
tbl1.ID,
tbl2.ENTRY_VALUE,
tbl2.STATUS
From
tbl1
Inner Join
tbl2 On tbl1.ID = tbl2.ID
Where
Abs([tbl1].[ENTRY_VALUE] - [tbl2].[ENTRY_VALUE]) =
(Select Min(Abs([tbl1].[ENTRY_VALUE] - [T2].[ENTRY_VALUE])) As Offset
From tbl2 As T2
Where T2.ID = tbl1.ID);
Output:
ID | ENTRY_VALUE | 状态 |
---|---|---|
1001 | 1880年 | 成功 |
1002 | 1980 | 失败 |
请注意,如果一个 ID 的最小偏移量存在两次,则将返回具有此偏移量的两条记录。 因此,您可能必须聚合 output。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.