2009-08-05 16 views
0

私はいくつかのテーブルを持つデータベースを持っています。そのうちの5つは特定のパブリケーションタイプ専用です。これらの5つのそれぞれは、ステータステーブルと人物テーブルと1対多の関係を持っています。これらのテーブルはすべて、一意の「恥骨」を使用して結ばれています。私は恥ずかしそうな(すべての5つのタイプの)、関連するキーワードを含むビューを持っています。ユーザーがキーワード検索を行い、その結果がこれらの5つのパブリケーションタイプのテーブルのうちの1つ以上にまたがっている場合、私はそれをどのように処理するのか本当に分かりません。複数の1 - >多くの関係を扱うにはどうすればいいですか?

のみ1つのパブリケーションタイプネストされたが、参加して達成するのは非常に簡単だろう(>多くの1-持っていたので、ちょうど1つのテーブル)があった場合は、何かのように:その例で

SELECT * FROM articles 
    INNER JOIN status ON articles.spubid = status.spubid 
    INNER JOIN people ON articles.spubid = people.spubid 
    WHERE people.saffil = 'ABC' ORDER BY people.iorder, articles.spubid; 

'articles'は、私が言及した5つのテーブルのうちの1つで、>>多くの関係を持っています。キーワード検索は、記事、書籍、論文を含む検索結果を返します。どのように多くの異なるテーブルで同じ目的を達成できますか?そのような場合にJOINを使用する方法を理解しなければならない場合、デカルト積は非常に大きく、使用可能な形式に解析するオーバーヘッドが高すぎると思います。この場合の私の他の選択肢は何ですか?

+0

5つのテーブルに同じスキーマがありますか?あるいは、5つのテーブルからA、B、...、Zを選択することを実際に探していますか?選択したフィールドA〜Zが5つのスキーマの交差点にありますか? –

+0

現在、ビュー/ mviewsを含むいくつかのソリューションを試しています。 –

答えて

2

なぜ別のテーブルにあるのですか?列は異なっていますか?そして、どの列を返したいのですか(特に、ジョインを使って本番環境でselect *を使用することはありません)、クエリのさまざまな型間で違いはありますか?

同じ列になる場合は、UNION ALLを使用することをお勧めします。 union文の各部分に必要なものすべてを提供することで(テーブルのセットに含まれていない列に対してnullの値を与えることによって)列が異なる場合でも、依然として必要なものを得ることができます。簡略化されたコードは次のとおりです。

SELECT articlename, articlestatus, author, ISBN_Number 
FROM articles 
    INNER JOIN status ON articles.spubid = status.spubid 
    INNER JOIN people ON articles.spubid = people.spubid 
WHERE people.saffil = 'ABC' 
UNION ALL 
SELECT papername, paperstatus, author, null 
FROM papers 
    INNER JOIN status ON papers.spubid = status.spubid 
    INNER JOIN people ON papers.spubid = people.spubid 
WHERE people.saffil = 'ABC' 
+0

残念ながら、各テーブル間でカラムが多少異なり、戻ってくるすべてのものをスペルアウトすると(各テーブルは50カラム近くあります)、実際には読みにくく、ほとんど不可能になります。 –

+0

オブジェクトブラウザから列名をドラッグすると、それほど難しくありません。そして正直なところ、あなたが必要としないものについて考える必要があります。たとえば、結合フィールドは複数のテーブルで繰り返され、すべて返されるべきではありません。ちょうど帯域幅が無駄になります。) – HLGEM

0

あなたが検索していると、おそらくあなたはおそらくあなたのキーワードを使用して、すべての5つのビューを使用するストアドプロシージャを呼び出す、5種類(などvwBook、vwArticle、)

のそれぞれのビューを作成することができますそれを投げる。 5つの結果のそれぞれは、ストアドプロシージャのテーブル変数に格納されます。

もちろん、あなたの意見が正しいと思います。広いストロークの例を次に示します。

create proc MySearch 

@MySearchTerm varchar(50) 

AS 
    DECLARE @SearchResultsTABLE 
    (
    Type  varchar(10) -- the view you found the result in. 
    ,ID  int -- the primary key of the Book record. whatever you want to link it back to the original 
    ,FoundText varchar(512) 
    --etc 
    ) 

    INSERT INTO @SearchResults(Type, ID, FoundText) 
     SELECT 'Articles', ID, SomeKeyField 
     FROM vwArticle 
     WHERE SomeKeyField LIKE '%' + @MySearchTerm + '%' 

    INSERT INTO @SearchResults(Type, ID, FoundText) 
     SELECT 'Book', ID, SomeKeyField 
     FROM vwBook 
     WHERE SomeKeyField LIKE '%' + @MySearchTerm + '%' 

    --repeat as needed with the 3 other views that you'd build 

    SELECT * FROM @SearchResults 
2

さまざまなテーブルのすべてのユニオンであるビューを作成できます。トリッキーなことは、UNIONされたすべてのクエリに同じフィールドがあることを確認することです。そのため、それぞれにいくつかスタブを付ける必要があります。

CREATE VIEW AllTables AS 
    SELECT Afield1, Afield2, NULL as Bfield1, NULL as Bfield2 FROM Atable 
    UNION 
    SELECT NULL as Afield1, NULL as Afield2, Bfield1, Bfield2 FROM Btable; 

もちろん、必要に応じてスタブ値としてNULL以外の値を使用することもできます。次に、ビューに対してクエリを実行します。パブリケーションの種類に応じて書式を変更する必要がある場合は、元のテーブルをビューの一部として含めることができます(つまり、"'magazine' AS publication_type"または選択したものと同様のものを追加します)。

0

ここのテーブルデザインは本当に好きではありません。しかし、私は最初からデータベース全体を再設計するのはちょっと極端すぎると思います。

テーブルの設計を考えれば、UNIONに移動して各テーブルの列を指定する必要があると思います。私はそれがモンスターであることを知っていますが、それは "ほぼ"同様の列をたくさん持つテーブルを設計するときに起こります。

HLGEMが正しいです。永久に保存されたクエリで "select *"を使うのは本当に危険です。

+0

はいユニオンは実行可能なオプションであることが証明されています。私はyo8u A.Lに同意します。私はそのデザインも気にしません。私が取る予定の解決策(今日のテスト)は、5つのテーブル(およびおそらく人物テーブルも同様)からマテリアライズドビューを作成して、非常に単純な単一の結合を行うことができます。 –

0

私たちは結局、ビュー内に配列の列として1つのテーブルを含む非常に精巧なビューを作成しました。これにより、1つのビューで1つのクエリを実行でき、必要なすべてのデータが返されます。ビューの定義は非常に複雑ですが、それはチャンピオンのように働いていますが、実際のトリックはPostgreSQLのARRAY()関数を使用していました。

関連する問題