我正在尝试加入两个这样的表:
表A
A1, A2, A3
A, 1, 35
A, 1, 70
A, 1, 105
表B
B1,B2, B3
B, 1, 30
C, 1, 32
D, 1, 40
E, 1, 55
F, 1, 60
G, 1, 77
H, 1, 80
预期结果如下:
A, 1, 35, C, 32
A, 1, 70, F, 60
A, 1, 105, H, 80
也就是说,对于表A中的每一行,我想从表B中选择一行,它应该是值B3较小但最接近A3值的行。
到目前为止,我已尝试过以下查询:
SELECT A1, A2, A3, B1, B3 FROM A JOIN (SELECT B1, B2, B3 FROM B ORDER BY B2, B3 DESC) AS A ON A.A2 = B.B2 AND A.B3 < A.A3
但是,这会产生如下表格:
A, 1, 35, B, 30
A, 1, 35, C, 32
A, 1, 70, B, 30
A, 1, 70, C, 32
A, 1, 70, D, 40
A, 1, 70, E, 55
等等。我还尝试在内部SELECT中添加LIMIT 1,但这不会产生任何结果。如果我自己运行内部查询(使用LIMIT 1),我会得到预期的结果。如何更改查询以生成所需结果?我目前正在使用sqlite,但想以可移植到其他DBMS的方式编写它。
答案 0 :(得分:1)
尝试以下查询:
SELECT
a.A1,
a.A2,
a.A3,
(
SELECT b.B3
FROM TableB AS b
ORDER BY ABS(a.A3 - b.B3)
LIMIT 1
) AS x
FROM TableA AS a;
SQL Fiddle不会让我使用sqlite,因为我的浏览器不支持它,所以我希望这适合你。
编辑:这实际上应该为您提供最接近的值。 77接近70而不是60 ......但我不知道这是不是你想要的。
答案 1 :(得分:1)
如果您只需要初始表中的一行,那么您可以考虑在select
子句中使用子查询:
select a.*,
(select b3
from TableB b
where b.b3 <= a.a3
order by b3 desc
limit 1
) as b3
from TableA a
子查询本身称为“相关子查询”,因为where
子句引用内部表(b
)和外部表(a
)。它按b3对表b的结果进行排序,过滤掉除每行中小于或等于a.a3
的所有值。 limit 1
返回单个值,因为排序是最接近的值小于或等于a.a3
中的值。
您的问题是最接近的值,但示例结果的最大值小于或等于。
答案 2 :(得分:0)
我没有SQLite可用,但以下工作在SQL Server中;你应该可以用LIMIT替换TOP。
只要您指定TOP 1,您就应该能够从select中的嵌套查询中获取它:
select *,
(select top 1 B3
from B
where B3 <= A3
order by B3 desc)
from A
编辑:要从B添加额外列,需要将上述查询嵌套到子查询中:
select t.*, B.B1 from (
select *,
(select top 1 B3
from B
where B3 <= A3
order by B3 desc) as B3
from A
) as t join B on B.B3 = t.B3