任何人都可以告诉我,如果可以在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)
- name(来自cms_pages_translations)
- 内容(来自cms_pages_translations)
- 别名(来自cms_pages_translations)
答案 0 :(得分: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。最好的事情是fire 2查询条件(如注释中所述)并在cms_pages_translations上创建一个索引(cms_pages_id,cms_languages_id)
答案 1 :(得分: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)
如果存在,将返回两个表的所有字段。假设“name”,“alias”和“content”的数据只出现在两个表中的一个表中,那么就可以执行此操作。
答案 2 :(得分: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;
}