[英]Conditional JOIN produces two many rows
我正在嘗試加入兩個像這樣的表:
表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的方式編寫此代碼。
請嘗試以下查詢:
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比60更接近70 ...但是我不知道這是否正是您想要的。
當您只需要從初始表中獲取一行時,可以考慮在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
, a.a3
每行中小於或等於a.a3
的值。 limit 1
返回單個值,由於排序,該值是小於或等於a.a3
的值的最接近值。
您的問題是最接近的值,但是示例結果的最大值小於或等於。
我沒有可用的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.