我正在尝试使用 Zend 函数调用来构建查询来重现以下 SQL:
SELECT `0`.`id`, `0`.`abbrev` FROM
(SELECT `abbreviations`.`id`, `abbreviations`.`abbrev`
FROM `abbreviations` , `keywords`
WHERE `keywords`.`keyword` LIKE 'aug%'
AND `keywords`.`abbrev_id` = `abbreviations`.`id`) `0`
INNER JOIN
(SELECT `abbreviations`.`id`
FROM `abbreviations` , `keywords`
WHERE `keywords`.`keyword` LIKE 'foo%'
AND `keywords`.`abbrev_id` = `abbreviations`.`id`) `1`
ON (`0`.`id` = `1`.`id`)
INNER JOIN
(SELECT `abbreviations`.`id`
FROM `abbreviations` , `keywords`
WHERE `keywords`.`keyword` LIKE 'augment%'
AND `keywords`.`abbrev_id` = `abbreviations`.`id`) `2`
ON (`0`.`id` = `2`.`id`)
ORDER BY `0`.`abbrev`
我知道这个 SQL 在我测试过它时有效。我更喜欢使用 SQL“INTERSECT”,但由于 MySQL 不支持它(就此而言,我不知道 Zend 是否也支持),我不得不使用子查询。
我遇到的困难是通过使用链接函数调用(例如 $this->getDbTable()->select()->from() 等)创建查询来以“Zend 方式”进行操作。
例如,我已经能够成功地创建子查询之一:
public function selectAbbrevIdsByKeyword($keyword, $abbrevFields) {
return $this->getDbTable()->select()
->from(array('a' => 'abbreviations'), $abbrevFields)
->from(array('k' => 'keywords'), 'abbrev_id')
->where('`k`.`keyword` LIKE ?', $keyword . '%')
->where('`k`.`abbrev_id` = `a`.`id`')
->setIntegrityCheck(false);
然而,当我尝试将子查询组合到我的整体目标 SQL 语句中时,这一切都崩溃了:
$all_abbrev_cols = array('id', 'abbrev');
$first_subselect = $this->selectAbbrevIdsByKeyword('foo', $all_abbrev_cols);
$select = $this->getDbTable()->select();
$select->from(array('0' => $first_subselect), $all_abbrev_cols);
$select->join(array("1" =>
$this->selectAbbrevIdsByKeyword($keywords[1],
array('id'))), "`0`.`id` = `1`.`id`");
$select->setIntegrityCheck(false);
Zend_Debug::dump($select->__toString());
通过“崩溃”,我的意思是产生了令人困惑的 SQL,尤其是所有无关的反引号。
string(1006)
"SELECT ```id``)`.`id`, ```id``)`.`abbrev`, ```id``)`.`description`, ```id``)`.`status`, ```id``)`.`rec_practice`, ```id``)`.`type`, ```id``)`.`category`, `SELECT ``a``.``id``, ``k``.``abbrev_id`` FROM ``abbreviations`` AS ``a``
INNER JOIN ``keywords`` AS ``k`` WHERE (``k``.``keyword`` LIKE 'aug%') AND (``k``.``abbrev_id`` = ``a``.``id``)_2`.* FROM (SELECT `a`.`id`, `a`.`abbrev`, `a`.`description`, `a`.`status`, `a`.`rec_practice`, `a`.`type`, `a`.`category`, `k`.`abbrev_id` FROM `abbreviations` AS `a`
INNER JOIN `keywords` AS `k` WHERE (`k`.`keyword` LIKE 'foo%') AND (`k`.`abbrev_id` = `a`.`id`)) AS ```id``)`
INNER JOIN (SELECT `a`.`id`, `k`.`abbrev_id` FROM `abbreviations` AS `a`
INNER JOIN `keywords` AS `k` WHERE (`k`.`keyword` LIKE 'aug%') AND (`k`.`abbrev_id` = `a`.`id`)) AS `SELECT ``a``.``id``, ``k``.``abbrev_id`` FROM ``abbreviations`` AS ``a``
INNER JOIN ``keywords`` AS ``k`` WHERE (``k``.``keyword`` LIKE 'aug%') AND (``k``.``abbrev_id`` = ``a``.``id``)_2` ON `0`.`id` = `1`.`id`"
有没有办法通过链式 Zend 函数调用生成 SQL 的“Zend 方式”,或者我应该放弃并说这个查询太复杂,而是将查询构建为字符串(使用 Zend_Db_Expr 和/或 quoteInto 用于参数/引用)?