Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用Zend生成多个子查询_Php_Sql_Zend Framework - Fatal编程技术网

Php 使用Zend生成多个子查询

Php 使用Zend生成多个子查询,php,sql,zend-framework,Php,Sql,Zend Framework,我尝试使用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` = `abbrev

我尝试使用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作为参数/引用)?

我最终做了Aaron在评论中描述的事情,只是因为我已经拥有的代码最简单

我编写了一个helper函数,它使用基于参数构建子查询的标准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)
              ->__toString();
}
然后,我使用子查询助手方法将查询构建为一个大字符串,并使用Zend_Db_Adapter的query()函数提交所有查询:

$all_abbrev_cols = array('id', 'abbrev', 'description', 'status', 'rec_practice', 'type', 'category'); 
$sql = 'SELECT DISTINCT ';
foreach ($all_abbrev_cols as $col) {
  $sql .= "`0`.`$col`, ";
}
$sql = substr_replace($sql, '', -2); // remove last comma-space
$sql .= " FROM \n\n";

// first subquery is special, has all cols and is "0"
$sql .= '  (';
$sql .= $this->selectAbbrevIdsByKeyword($keywords[0], $all_abbrev_cols);
$sql .= ") `0`\n\n";

// starting on SECOND element (index 1)
for ($i = 1; $i < count($keywords); $i++) {
  $sql .= "INNER JOIN\n\n  (";
  $sql .= $this->selectAbbrevIdsByKeyword($keywords[$i], array('id'));
  $sql .= ") `$i`\n\nON (`0`.`id` = `$i`.`id`)\n\n";
}

$sql .= 'ORDER BY `0`.`status`, `0`.`abbrev`';

$entities = array();
foreach ($this->getDb()->query($sql)->fetchAll() as $row) {
  $entities[] = $this->_populate($row);
}
return $entities;
$all_abbrev_cols=数组('id','abbrev','description','status','rec_practice','type','category');
$sql='selectdistinct';
foreach($col){
$sql.=“`0`.`$col`,”;
}
$sql=substr_replace($sql,,-2);//删除最后一个逗号空格
$sql.=“来自\n\n”;
//第一个子查询是特殊的,具有所有COL且为“0”
$sql.='(';
$sql.=$this->selectabbrevdsbykeyword($keywords[0],$all_abbrev_cols);
$sql.=“0`\n\n”;
//从第二个元素(索引1)开始
对于($i=1;$iselectAbbrevdsbyKeyword($keywords[$i],数组('id'));
$sql.=”`$i`\n\n(`0`.`id`=`$i`.`id`)\n\n”;
}
$sql.='ORDER BY`0`.`status`、`0`.`abbrev`;
$entities=array();
foreach($this->getDb()->query($sql)->fetchAll()作为$row){
$entities[]=$this->\u填充($row);
}
返回$实体;

这产生了与我原始问题中的SQL语句相匹配的查询结果。

您可以用“zend方式”来实现这一点,但这几乎太令人头痛了。我见过的最好的混合是程序员将使用zend_db_select()构建每个子选择,然后得到该子选择的u toString()版本。。。然后使用zend_db_表达式创建最终的zend_db_select以包含所有这些字符串。到那时,您最好只使用标准查询();我将在下面发布更多信息,供其他人将来参考