0

垂直テーブルの2行をフラット化する必要があります(次に3番目のテーブルに結合します)。これは通常、必要なフィールドごとに派生テーブルを作成することによって行います。フィールドは2つしかないので、これはそれほど不合理ではないと思います。

しかし、派生テーブルに戻したい行は、3番目のテーブルとの結合にあるサブセットであることを私は知っています。そのため、クエリが最も効率的に実行されるように、作成するのに最適な派生テーブルを見つけようとしています。

派生テーブルのwhere句を制限するほど、派生テーブルが小さくなるほど、より良い応答が得られると思います。

本当に私が欲しいのは、派生テーブルのwhere句を3番目のテーブルとの結合と相関させることですが、SQLではそれを行うことができません。これは残念です。しかし、私はSQLマスターではありません。おそらく、私が知らないトリックがいくつかあります。

もう1つのオプションは、where句を使用せずに派生テーブルを作成することです。これにより、テーブル全体が2回(フィールドごとに1回)結合され、結合を実行すると、結合によってすべてが除外されます。

だから本当に私が求めているのは、私が欲しい行をかなり具体的に知っている派生テーブルを作成するための最良の方法ですが、SQLではそれらを取得できません。

例:

table1
------

id  tag     value
--  -----   -----
1   first   john
1   last    smith
2   first   sally
2   last    smithers


table2
------

id     occupation
--     ----------
1      carpenter
2      homemaker


select table2.occupation, firsttable.first, lasttable.last from
table2, (select value as first from table1 where tag = 'first') firsttable,
(select value as last from table1 where tag = 'last') lasttable
where table2.id = firsttable.id and table2.id = lasttable.id

私がやりたいのは、tag='first'およびid=table2.idであるfirsttablewhere句を作成することです。

4

3 に答える 3

1

DERIVED テーブルは、期待どおりに中間結果を格納するものではありません。これらは、コードを単純にするための方法にすぎません。派生テーブルを使用しても、派生テーブル式が最初に実行され、その出力が残りのテーブルと結合するために使用されるという意味ではありません。ほとんどの場合、オプティマイザーは自動的に派生テーブルを無効にします。

ただし、オプティマイザーがサブクエリの結果を格納して、フラット化ではなく実体化したい場合があります。通常、何らかの集計関数がある場合などに発生します。しかし、あなたの場合、クエリは単純すぎるため、オプティマイザはクエリを平坦化します

また、派生テーブル式を格納してもクエリが高速化されず、さらに悪化する可能性があります.実際の問題は、正規化が多すぎることです.クエリが2つのテーブルの単なる結合になることを修正してください.

なぜこの種の正規化を行うのですか?なぜ列の値を行として保存するのですか?最初と最後に 2 つの列があるように、table1 を非正規化してみてください。これが最善の解決策です。

また、id および tag 列に適切なインデックスがありますか? はいの場合、マージ結合はクエリに非常に適しています。

これらのテーブルのインデックスの詳細と、クエリによって生成されたプランを提供してください。

クエリは、内部結合クエリのように使用されます。

select table2.occupation, first.valkue as first, last.value as last 
from 
table2
inner join table1  first 
on first.tag = 'first'
and first.id =table2.id
inner join table1 last
on last.tag = 'last'
and table2.id = last.id 
于 2012-07-23T13:45:37.733 に答える
0

私は少し混乱しています。クエリは問題ないようです。。。適切な結合構文を使用すると見栄えが良くなりますが。

select table2.occupation, firsttable.first, lasttable.last
from table2 join
       (select value as first from table1 where tag = 'first') firsttable
       on table2.id = firsttable.id join
       (select value as last from table1 where tag = 'last') lasttable
       on table2.id = lasttable.id 

このクエリは、要求されていることを実行します。SQLは宣言型言語であり、手続き型言語ではありません。これは、結果セットを記述し、データベースSQLコンパイラーに依存してそれを適切なコマンドセットに変換することを意味します。(とはいえ、クエリがどのように構成されているかによって、一部のエンジンが効率的なクエリプランを作成するのが簡単または困難になる場合があります。)

于 2012-07-23T13:09:56.063 に答える
0

あなたが求めているのはCOMMON TABLE EXPRESSION. プラットフォームがそれらを実装していない場合は、一時テーブルが最適な代替手段になる可能性があります。

于 2012-07-23T12:46:14.040 に答える