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

您可以尝试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 一次只能重新运行一列。因此您可以单独查询每个列。

或者你试试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)

如果它们存在,它将返回两个表的所有字段。假设“名称”、“别名”和“内容”的数据将只出现在一个 pageID 的两个表之一中,这将执行此操作。

于 2012-11-21T13:09:54.523 回答
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

您可以尝试使用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 回答