2012-04-28 13 views
1

私はこれまでずっとこれを見てきました。私の脳はスパゲティのような感じです。誰かが2つの質問で私を助けてくれますか?複数のテーブルを結合して、特定の条件に基づいて結果をフェッチするにはどうすればよいですか?

テーブル

私はこの時点で尋ねるする必要がは、「このテンプレートのために私の資産とその位置のすべてを与える。」基本的にはあると思い
Presentation 
------------ 
id   int 
name  varchar 
fk_template int  (references template.id) 

Template 
-------- 
id   int 
name  varchar 

Position 
-------- 
id   int 
zorder  int  (if it is the 1st, 2nd, 3rd position of the given template) 
fk_template int  (references Template.id) 

Asset 
----- 
id   int 
name  varchar 
description varchar 

AssetForPresentation 
-------------------- 
fk_asset  int (references Asset.id) 
fk_presentation int (references Presentation.id) 
fk_position  int (references Position.id) 

プレゼンテーションを持って来ると、特定のテンプレートが表示されます。各テンプレートは位置を指定し、各位置は資産またはNULLを保持します。

プレゼンテーションで使用される特定のテンプレートのすべての資産とその個々のポジションを持ち込むことができる必要があります。 どうすればそのようなことをクエリできますか?

これはあなたにとって理にかなっていると思います。

+0

ご質問はありますか? – Hamish

+0

私はこれをどのようにクエリするかを尋ねています...それは私が書いたものを通して明確に結びついているだけでなく、この質問のタイトルは単純な「SQL:すべての資産とそのポジションを選択する」と述べています...私は "SQL"ソリューションを探している場合は常に私のタイトルの前に "SQL"と書かれています。 – dcolumbus

+0

@シヴァのコメントありがとう。 – dcolumbus

答えて

2

私はあなたが苦労している部分がAssetForPresentationテーブルにJOIN上の2つの条件だと思います。

SELECT 
    a.id, 
    a.name, 
    a.description 
FROM Presentation AS p 
JOIN Template AS t 
    ON p.fk_template = t.id 
LEFT JOIN Position AS pos 
    ON pos.fk_template = t.id 
LEFT JOIN AssetForPresentation AS afp 
    ON afp.fk_presentation = p.id 
    AND afp.fk_position = pos.id 
LEFT JOIN Asset AS a 
    ON a.id = afp.fk_asset 
WHERE p.id = 123 
ORDER BY pos.zorder ASC 
+0

はい、私は確かにそれで苦労しています。私はちょうど今すぐスクランブルしているので、私は何を求めているのか分かりません。:/ – dcolumbus

+0

@dcolumbus私のクエリがうまく動作するかどうかをチェックしてください。 –

+0

結果は少しです。いくつかの選択フィールドに「*」を絞り込むと、あまりにも曖昧さが増します。 – dcolumbus

2

質問に記載されている内容に基づいて、特定のテンプレートのすべてのアセットを取得する必要があります。テーブル構造を作成しましたが、テーブルの関係制約は定義しませんでしたが、クエリを定式化する際に使用しました。

AssetテーブルをAssetForPresentationテーブルに参加させることができます。 AssetForPresentationテーブルを使用して、PresentationテーブルとPositionテーブルを結合することができます。 Templateとの関係は、Positionテーブルを介して行うことができます。したがって、テンプレートテーブルを資産セットテーブルに結合して、すべての一致するレコードを取得します。

以下のリンクからデモをご覧いただけます。

Click here to view the demo in SQL Fiddle.

お役に立てば幸いです。

スクリプト:

CREATE TABLE Presentation 
(
     id   INT   NOT NULL AUTO_INCREMENT 
    , name  VARCHAR(30) NOT NULL 
    , PRIMARY KEY (id) 
); 

CREATE TABLE Template 
(
     id   INT   NOT NULL AUTO_INCREMENT 
    , name  VARCHAR(30) NOT NULL 
    , PRIMARY KEY (id) 
); 

CREATE TABLE Position 
(
     id   INT   NOT NULL AUTO_INCREMENT 
    , zorder  INT   NOT NULL 
    , fk_template INT   NOT NULL 
    , PRIMARY KEY (id) 
); 

CREATE TABLE Asset 
(
     id   INT   NOT NULL AUTO_INCREMENT 
    , name  VARCHAR(30) NOT NULL 
    , description VARCHAR(30) NOT NULL 
    , PRIMARY KEY (id) 
); 

CREATE TABLE AssetForPresentation 
(
     fk_asset  INT   NOT NULL 
    , fk_presentation INT   NOT NULL 
    , fk_position  INT   NOT NULL 
); 

INSERT INTO Presentation (name) VALUES 
    ('presenation 1'), 
    ('presenation 2'); 

INSERT INTO Template (name) VALUES 
    ('template 1'), 
    ('template 2'); 

INSERT INTO Position (zorder, fk_template) VALUES 
    (1, 1), 
    (2, 2); 

INSERT INTO Asset (name, description) VALUES 
    ('asset 1', 'asset description 1'), 
    ('asset 2', 'asset description 2'); 

INSERT INTO AssetForPresentation (fk_asset, fk_presentation, fk_position) 
VALUES 
    (1, 1, 1), 
    (1, 2, 1), 
    (2, 2, 1), 
    (2, 2, 2); 

SELECT    * 
FROM    Asset A 
RIGHT OUTER JOIN AssetForPresentation AP 
ON     A.id = AP.fk_asset 
RIGHT OUTER JOIN Presentation P 
ON     P.id = AP.fk_presentation 
RIGHT OUTER JOIN Position PO 
ON     PO.id = AP.fk_position 
RIGHT OUTER JOIN Template T 
ON     T.id = PO.fk_template 
WHERE    T.id = 1; 

出力

ID NAME DESCRIPTION   FK_ASSET FK_PRESENTATION FK_POSITION ZORDER FK_TEMPLATE 
-- ------- ------------------- -------- --------------- ----------- ------ ----------- 
1 asset 1 asset description 1 1   1   1   1  1 
1 asset 1 asset description 1 1   2   1   1  1 
2 asset 2 asset description 2 2   2   1   1  1 
+0

うわー...あなたの反応に多大な努力を尽くしてくれてありがとう。それは巨大な助けです!私はこれを見て、あなたがここで何をやっているのか理解していることを確認します。ありがとうございました! – dcolumbus

+0

すべての結合は「INNER JOIN」です。したがって、クエリでは、それぞれの位置に常にアセットがあるとみなされます。しかし、あるポジションについて資産がない場合、このポジションは結果セットに表示されません。 OPの要件に合わないようだ。 –

+0

まあ、結局、私はこれを配列としてビューに表示できることが大好きです。配列をループすることができ、位置が 'empty()'または 'NULL'ならば、それはうまくいくはずです...そのレコードは' Save(保存)時に 'AssetForPresentation'テーブルに作成されません) '...それは論理的だと思われますか? – dcolumbus

関連する問題