簡體   English   中英

條件JOIN產生兩行

[英]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小提琴

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.a3a.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM