SQL如何使用同一列中的值之间匹配2个表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL如何使用同一列中的值之间匹配2个表相关的知识,希望对你有一定的参考价值。

我正在努力从表A中选择表B中同一列中值之间的记录。请在此处查看这些表的基本结构:

表A.

Id   Depth           Comment         
1    150            Status is good
2    215            Status is good
3    330            Status is bad

表B.

    Id   Depth          Material        
    1    130            Hard
    2    200            Soft
    3    220            Very Hard
    4    280            Very Hard
    5    350            Soft

所以,我要做的是选择表A中的所有值,这些值高于表B中的深度,但低于下一个值(在同一列中的值之间的范围内).Depth和display Comments&材料。我期待的结果是:

    Depth  Comment          Material         
    150    Status is good   Hard
    215    Status is good   Soft
    330    Status is bad    Very Hard

任何帮助将受到高度赞赏,谢谢!

答案

您可以为此使用相关子查询。确切的语法取决于数据库,但它们都很简单。这是ANSI标准语法:

select a.*,
       (select material
        from b
        where a.depth >= b.depth
        order by b.depth desc
        fetch first 1 row only
       ) as material
from a;

根据数据库,fetch first 1 row only可能是limit 1或它可能是select top 1或它可能完全是其他东西。

编辑:

mysql中,你会这样做:

select a.*,
       (select material
        from b
        where a.depth >= b.depth
        order by b.depth desc
        limit 1
       ) as material
from a;

在MS Access中:

select a.*,
       (select top 1 material
        from b
        where a.depth >= b.depth
        order by b.depth desc, b.id
       ) as material
from a;

在Oracle 12g中,上述工作正常。在其他版本中,它稍微复杂一些:

select a.*,
       (select distinct first_value(material) over (order by b.depth desc)
        from b
        where a.depth >= b.depth
       ) as material
from a;
另一答案

假设ID是相关的,并且您希望看到的深度是TableA中的ID

SELECT a.Depth, a.Comment, b.Material
FROM Tablea a
INNER JOIN Tableb b ON a.ID = b.ID
WHERE a.Depth > b.Depth
另一答案

以下将在Oracle上执行。注释掉“from dual”并将“Comment”更改为[Comment],它也将在SQL Server上执行。它只提供您显示的输出。它甚至可以在MySql中执行,但您必须将数据存储在实际表中而不是使用CTE。

with
TableA( Id, Depth, "Comment" )as(
  select  1, 150, 'Status is good' from dual
  union all
  select  2, 215, 'Status is good' from dual
  union all
  select  3, 330, 'Status is bad' from dual
),
TableB( Id, Depth, Material )as(
  select  1,    130,            'Hard' from dual
  union all
  select  2,    200,            'Soft' from dual
  union all
  select  3,    220,            'Very Hard' from dual
  union all
  select  4,    280,            'Very Hard' from dual
  union all
  select  5,    350,            'Soft' from dual
)
select  a.Depth, a."Comment", b.Material
from  TableA  a
join  TableB  b
  on  b.Depth =(
        select  Max( Depth )
        from    TableB
        where   Depth <= a.Depth );

诀窍是将TableB的每一行与TableB的一行连接,其中最大深度值小于或等于TableA中行的深度值。不要让子查询抛弃你。假设深度已编入索引,这与任何其他方法的表现相同或更好。但是如果TableB与你所展示的一样小,那么无论如何它都将被读入缓存。

以上是关于SQL如何使用同一列中的值之间匹配2个表的主要内容,如果未能解决你的问题,请参考以下文章

当同一列中的值不匹配但不同列重复时将返回结果的 SQL 查询

比较 2 个表中的值并生成具有差异的新表

SQL 删除行,其中一个值与 DIFFERENT 列中的值匹配

从 2 个表中获取数据

SQL - 如何使用用户定义的函数来约束 2 个表之间的值

如何将 SQL 中的 2 个表与 1 个公共列组合在一起,而其他列中没有关系?