繁体   English   中英

在另一个表中查找最接近的值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM