1

次のような2つのテーブルを結合しようとしています:

表 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 から 1 行だけを選択します。これは、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 に移植可能な方法で記述したいと考えています。

4

3 に答える 3

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フィドル

SQL Fiddleでは、ブラウザがsqliteをサポートしていないため、sqliteを使用できません。これが機能することを願っています。

編集:これは実際にあなたに最も近い値を与えるはずです。77は60より70に近いです...しかし、これがまさにあなたが望んでいたものであるかどうかはわかりません。

于 2013-03-18T15:25:34.163 に答える
1

select初期テーブルから正確に1行が必要な場合は、次の句でサブクエリを使用することを検討できます。

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)の両方を参照するためです。a.a3テーブルbの結果をb3で並べ替え、各行の値以下の値を除くすべてを除外します。は単一のlimit 1値を返します。これは、並べ替えのために、の値以下の最も近い値ですa.a3

あなたの質問は最も近い値を示していますが、例の結果は以下の最大値を持っています。

于 2013-03-18T15:48:44.567 に答える
0

SQLite は利用できませんが、SQL Server では次のように動作します。TOP を LIMIT に置き換えることができるはずです。

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
于 2013-03-18T15:27:15.110 に答える