1

(SQL SERVER 2008) マスター/ベース テーブルに結合するために、複数のテーブルにタイムスタンプ付きのレコードがあります。タイムポイントがベース テーブルと等しい場合もあれば、そうでない場合もあります。

テーブルを作成するコード:

create table base (time float);
create table table2 (time float, val2 char(1));
create table table3 (time float, val3 int);
insert into base values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
insert into table2 values (1, 'a'),(5, 'z'),(6, 'm'),(9, 'b');
insert into table3 values (1.5, 1),(5.3, 10),(5.5, 0),(8.1, 4);

結果セットは、ベース テーブルからのレコードごとに 1 行であり、他のテーブルからの "最新" の値である必要があります。以前は、これらのテーブルは Excel で Vlookup を TRUE に設定して "結合" していました。

最終結果は次のようになります。

time | val2 | val3
1  | a | NULL
2  | a | 1
3  | a | 1
4  | a | 1
5  | z | 1
6  | m | 0
7  | m | 0
8  | m | 0
9  | b | 4
10 | b | 4

これを SQL ステートメントで複製するにはどうすればよいですか?

再生中のレコードは 100 までしかないため、ここでは効率より読みやすさを重視します。

4

2 に答える 2

3

おそらく、最も読みやすいのは、select句内の相関サブクエリです。

私は一般的にselectwithinのファンではありませんselectが、相関サブクエリは Excel vlookup の動作を模倣しています。

Select
  b.time,
  (Select max(t2.val2) From table2 t2 Where b.time >= t2.time) As val2,
  (Select max(t3.val3) From table3 t3 Where b.time >= t3.time) As val3
From
  base b
Order By
  b.time;    

http://sqlfiddle.com/#!3/3545e/18

(上記のコードと SQL Fiddle を提供してくれた Laurence に感謝します。)

を使用するにmaxは、値が非減少である必要があります。次のバージョンは関係なく動作します。

select
  b.time,
  (select top 1 t2.val2 from table2 t2 where b.time >= t2.time order by t2.time Desc) as val2,
  (select top 1 t3.val3 from table3 t3 where b.time >= t3.time order by t3.time Desc) as val3
from
  base b

http://sqlfiddle.com/#!6/a5148/5

于 2013-01-18T19:43:14.770 に答える
2

一般的な原則は、外部結合を使用して、2 番目のテーブルに一致がない場合でも確実に結果を取得することです。次に、不等式を使用して、超過するものを制限し、max残っているものの中で最高のものを選択できます。

基本的に と のクロス結合を行っているため、これは大きなテーブルでは非効率的である可能性がt2ありt3ます。それぞれネストされたクエリを実行し、後で結果を結合することをお勧めします。

-- Easier to read    
Select
  b.time,
  max(t2.val2) As val2,
  max(t3.val3) As val3
From
  base b
    left outer join
  table2 t2
    on b.time >= t2.time
    left outer join
  table3 t3
    on b.time >= t3.time
Group By
  b.time
Order By
  b.time;

-- Probably faster
Select
  n.time,
  n.val2,
  Max(t3.val3)
From (
    Select
      b.time,
      Max(t2.val2) As val2
    From
      base b
        left outer join
      table2 t2
         On b.time >= t2.time
    Group By
      b.time
    ) n
    Left Outer Join
  table3 t3
    On n.time >= t3.time
Group By
  n.time,
  n.val2
Order By
  n.time;

http://sqlfiddle.com/#!3/3545e/15

于 2013-01-18T19:35:07.017 に答える