0

次のシナリオが Doctrine (および一般的に mysql) で達成できるかどうか、誰でも教えてくれますか?

シナリオ: 次のようなフィールドを持つテーブル cms_pages があります。

  • ID
  • cms_languages_id
  • 名前
  • コンテンツ
  • エイリアス

そして、次のようなフィールドを持つ cms_pages_translations という別のテーブル:

  • ID
  • cms_pages_id (外部キー)
  • cms_languages_id
  • 名前
  • コンテンツ
  • エイリアス

そして今、言ってみましょう

 $language_id = 2;

私は cms_pages をクエリして、cms_pages.cms_languages_id が $language_id と等しくないことを確認しています... (したがって、私のページのコンテンツは、探している言語ではありません)。でも、大丈夫です。翻訳が存在する cms_pages_translations というテーブルを取得しました。したがって、同じクエリで、一致する値 (名前、コンテンツ、エイリアス) を cms_pages_translations から取得する必要があります。

cms_languages_id == $language_id.

私が達成したいことが明確であることを願っています:)

したがって、クエリ出力データには次のものが含まれます。

  • id (cms_pages から)
  • 名前 ( cms_pages_translations から)
  • コンテンツ ( cms_pages_translations から)
  • エイリアス ( cms_pages_translations から)
4

3 に答える 3

0

cms_pages_id が cms_pages.id の外部キーである場合、すべての翻訳がこのテーブルに表示されるはずなので、cms_pages_translations でクエリを実行してみませんか。特定のページの翻訳を取得するには、$page_id が必要だと思います。

次のクエリを使用できます

SELECT id, NAME, content, alias FROM cms_pages WHERE id=1 AND cms_languages_id = 2
UNION
SELECT cms_pages_id, NAME, content, alias FROM cms_pages_translations WHERE cms_pages_id=1 AND cms_languages_id = 2 AND 0 = (SELECT COUNT(id) FROM cms_pages WHERE id=1 AND cms_languages_id = 2);

ただし、これはすべてのケースで cms_pages_translations を再度スキャンします。あなたにとって最善の方法は、条件付きで2つのクエリを実行し(コメントで述べたように)、cms_pages_translations(cms_pages_id、cms_languages_id)にインデックスを作成することです

于 2012-11-21T12:56:19.960 に答える
0

IFNULL次のような構造を試すことができます。

SELECT IFNULL(
    (SELECT content FROM cms_pages WHERE cms_languages_id=3 AND id=1), 
    (SELECT content FROM cms_pages_translations WHERE cms_languages_id=3 AND id=1)
  )

これに関する唯一のポイントは、IFNULL は一度に 1 つの列しか再実行できないということです。したがって、各列を個別にクエリできます。

または、次のように試してくださいJOIN

SELECT *
FROM cms_pages_translations t 
JOIN cms_pages p ON p.id=t.cms_pages_id
WHERE t.id=1 AND (t.cms_languages_id=1 OR p.cms_languages_id=1)

存在する場合、両方のテーブルのすべてのフィールドが返されます。「name」、「alias」、および「content」のデータが、1 つの pageID の両方のテーブルの 1 つにのみ存在すると仮定すると、これで十分です。

于 2012-11-21T13:09:54.523 に答える
0

MySQL Caseを試すことができます。私が覚えているように、Zend で直接使用することはできないため、Zend_Db_Expr.

public function getPageTranslated($page_id, $language_id) {
    $name = new Zend_Db_Expr("
        CASE 
            WHEN p.language_id = $language_id THEN p.name
            ELSE pt.name
        END
    ");

    $content = new Zend_Db_Expr("
        CASE 
            WHEN p.language_id = $language_id THEN p.content
            ELSE pt.content
        END
    ");

    $alias = new Zend_Db_Expr("
        CASE 
            WHEN p.language_id = $language_id THEN p.alias
            ELSE pt.alias
        END
    ");

    $select = $this->select()
            ->from(array('p' => 'cms_pages'), array('id' => 'p.id', 'name' => $name, 'content' => $content, 'alias' => $alias))
            ->where('p.id = ?', $page_id)
            ->joinLeft(array('pt' => 'cms_pages_translations'), 'p.id = pt.cms_pages_id', array('pt.name', 'pt.content', 'pt.alias'))
            ->where('pt.language_id = ?', $language_id)
            ->limit(1)
            ->setIntegrityCheck(false);

    $result = $this->fetchAll($select);

    return $result? $result->toArray(): false;
}
于 2012-11-21T13:30:25.440 に答える