2

問題があると思われる興味深いクエリがあります。

複数のテーブルからデータを選択し、他のテーブルには存在しない可能性がある列を持つ追加のテーブルに結合する必要があります。

私はこれについていくつかの角度を試しました。これが最初のものです:

SELECT SiteTree.*, Page.*, AlbumItem.*, Album.*
FROM SiteTree, AlbumItem, Album
LEFT JOIN Page ON SiteTree.ID = Page.ID

これをスローします: #1054 - 'on 句' の不明な列 'SiteTree.ID'。おそらく、Album テーブルから選択するときに結合しようとすると、SiteTree.ID 列がないためです。

私もこれを試しました:

SELECT SiteTree.*, Page.*, AlbumItem.*, Album.*
FROM SiteTree LEFT JOIN Page ON SiteTree.ID = Page.ID, AlbumItem, Album

これは約 20 行を返しますが、where 句に基づいて 2 つしかないことがわかっています。実際には、各結果行の約 10 のコピーがあります

ここで、句は次のとおりです。

WHERE (
    (
        AlbumItem.ClassName = 'AlbumItem' OR 
        Album.ClassName = 'Album' OR 
        SiteTree.ClassName = 'Page' OR 
        SiteTree.ClassName = 'HomePage' OR 
        SiteTree.ClassName = 'NewsCategory' OR
        SiteTree.ClassName = 'NewsArticle' OR
        SiteTree.ClassName = 'CartPage' OR
        SiteTree.ClassName = 'Product' OR
        SiteTree.ClassName = 'ProductGroup' OR
        SiteTree.ClassName = 'MemberProfilePage' OR
        SiteTree.ClassName = 'SubscriptionPage' OR
        SiteTree.ClassName = 'ErrorPage' OR
        SiteTree.ClassName = 'RedirectorPage' OR
        SiteTree.ClassName = 'VirtualPage' OR
        SiteTree.ClassName = 'UserDefinedForm' OR
        SiteTree.ClassName = 'CheckoutPage' OR
        SiteTree.ClassName = 'OrderConfirmationPage' OR
        SiteTree.ClassName = 'TagPage'
    ) AND (
       INSTR(Page.Tags,'x') OR
       INSTR(AlbumItem.Tags,'x') OR
       INSTR(Album.Tags,'x')
    )
)

クエリをこれに減らすと正しい結果が得られますが、他のテーブルでも機能しません。

SELECT SiteTree.*, Page.*
FROM SiteTree
LEFT JOIN Page ON SiteTree.ID = Page.ID

私が知る必要があるのは、私がやろうとしていることが組合に頼らずに可能かどうかです?

4

3 に答える 3

1

(カップル)完全な外部結合/相互結合の問題に対する実際の結合基準の欠如AlbumItemAlbumこれらの2つのテーブルを適切に結合する必要があります。それ以外の場合は、これらのテーブルごとに少なくとも1つのレコードを取得します。

于 2012-06-08T03:08:31.217 に答える
1

さて、私は今、作業中のクエリを持っています.

全体像を把握するために、SilverStripe でタグ付け可能なモジュールを構築していました。JOINSilverStripe の ORM を使用すると、 withON句 を実行する共通の列を共有しない一意のテーブル セットを持つ複数の DataObject に拡張機能を追加できます。

SQLQueryクエリを生成するときに、オブジェクトの制限に対処しようとしていました。SilverStripe の SQLQuery オブジェクトはサポートしていないUNIONので、生の SQL クエリを完全に生成する必要がないことを望んでいました。を使用せずにデカルト積の生成を回避する方法はないようUNIONです。

そのため、PDO の薄いラッパーを作成し、UNION以下に示すようにベースのクエリを使用することになりました。オブジェクトグラフをたどって関連するすべてのテーブルを見つけるスクリプトで自動的に生成されるため、手動で記述した場合よりも少し冗長になります。また、マッチングがより正確になるように正規表現一致を使用する必要がありますが、この時点では、使用可能な出力を生成するクエリにもっと関心がありました。

SELECT SQL_CALC_FOUND_ROWS SiteTree.ClassName, SiteTree.ID
FROM SiteTree LEFT JOIN Page ON SiteTree.ID = Page.ID
WHERE (
    SiteTree.ClassName = 'Page' OR 
    SiteTree.ClassName = 'HomePage' OR 
    SiteTree.ClassName = 'NewsCategory' OR 
    SiteTree.ClassName = 'NewsArticle' OR 
    SiteTree.ClassName = 'GalleryPage' OR 
    SiteTree.ClassName = 'CartPage' OR 
    SiteTree.ClassName = 'Product' OR 
    SiteTree.ClassName = 'ProductGroup' OR 
    SiteTree.ClassName = 'MemberProfilePage' OR 
    SiteTree.ClassName = 'SubscriptionPage' OR 
    SiteTree.ClassName = 'ErrorPage' OR 
    SiteTree.ClassName = 'RedirectorPage' OR 
    SiteTree.ClassName = 'VirtualPage' OR 
    SiteTree.ClassName = 'UserDefinedForm' OR 
    SiteTree.ClassName = 'CheckoutPage' OR 
    SiteTree.ClassName = 'OrderConfirmationPage' OR
    SiteTree.ClassName = 'TagPage'
) AND (
    INSTR(Page.Tags,'x')
)

UNION ALL

SELECT AlbumItem.ClassName, AlbumItem.ID
FROM AlbumItem
WHERE (AlbumItem.ClassName = 'AlbumItem') AND (INSTR(AlbumItem.Tags,'x'))

UNION ALL

SELECT Album.ClassName, Album.ID
FROM Album
WHERE (Album.ClassName = 'Album') AND (INSTR(Album.Tags,'x'))

LIMIT 0,40
于 2012-06-08T21:17:32.037 に答える
0

テーブルに名前IDの付いた列はありますか? SiteTreeエラーメッセージを考えると、ありません。これを修正して、テーブルに実際に存在する列を参照するようにします。

また、なぜANSI JOINs を実行しているのですか (つまり、, の使用) ... INNER JOINs である必要があります。そうしないと、期待どおりの結果が得られないからです。

于 2012-06-08T02:58:41.903 に答える