草庐IT

php - Zend_DB union() :Zend_Db_Table_Abstract 与 Zend_Db_Table::getDefaultAdapter()

coder 2024-05-04 原文

所以我有我想通过 zend 框架调用的原始 SQL

select t.type, t.tid,t.tname,t.cid,t.cname, ls.*
from
(
        select t.type, t.id as tid, t.name as tname, c.id as cid, c.name as cname from team t
        join company c on t.parent=c.id and t.type='C' and c.sector=20 and t.status='ACTIVE'
    union
        select t.type, t.id as tid,t.name as tname, null as cid, null as cname from team t
        join sector s on t.parent=s.id and t.type='S'and s.id=20 and t.status='ACTIVE'
) t
LEFT JOIN leaguesummary ls ON ls.leagueparticipantid=t.tid AND ls.leaguetype='T'
WHERE ls.leagueid = 5
ORDER BY ls.leaguedivision asc, ls.leagueposition asc LIMIT 10;    

我的模型类扩展了 Zend_Db_Table 我有一个简单的方法来构建 SQL 并查询它

class Model_DbTable_LeagueSummary extends Zend_Db_Table_Abstract {

....

public function getTeamLeagueSummayBySector($sectorid,$limit=10)
{
    $select = $this->select()
        ->setIntegrityCheck(false)
        ->from(array('team'=>'team'),array('type','id','name'))
        ->join(array('company'=>'company'),'team.parent=company.id',array())
        ->where('team.type="C"')
        ->where('team.status="ACTIVE"')
        ->where('company.sector=?',$sectorid);

    $select2 = $this->select()
        ->setIntegrityCheck(false)
        ->from(array('team'=>'team'),array('type','id','name'))
        ->join(array('sector'=>'sector'),'team.parent=sector.id',array())
        ->where('team.type="S"')
        ->where('team.status="ACTIVE"')
        ->where('sector.id=?',$sectorid);

    // manually creating the SQL string and calling Zend_Db_Table::getDefaultAdapter() directly
    $STRING = sprintf("select x.*,ls.* from ( %s union %s ) x
        LEFT JOIN leaguesummary ls ON ls.leagueparticipantid=x.id AND ls.leaguetype='T'
        WHERE ls.leagueid = 5
        ORDER BY ls.leaguedivision asc, ls.leagueposition asc LIMIT 10;",$select,$select2);
    $db = Zend_Db_Table::getDefaultAdapter();
    $stmt = $db->query($STRING);
    $stmt->setFetchMode(Zend_Db::FETCH_OBJ);
    $result = $stmt->fetchAll();
    return $result;
}

此查询有效,但不喜欢该解决方案并希望重构代码以更正确地使用 Zend_DB 方法。我已经走到这一步了

    $sql = $this->select()
        ->setIntegrityCheck(false)
        ->from(array('X'=>'X'))
        ->union(array($select,$select2))
        ->joinLeft(array('leaguesummary'=>'leaguesummary'),'leaguesummary.leagueparticipantid=X.id')
        ->where('leaguesummary.leaguetype="T"')
        ->where("leaguesummary.leagueid = ?",5)
        ->order("leaguesummary.leaguedivision asc")
        ->order("leaguesummary.leagueposition asc")
        ->limit($limit);
    return $db->fetchAll($sql);

但是我得到了这个异常(exception)。工会声明有什么问题?

Message: Invalid use of table with UNION

Stack trace:
#0 /home/assure/bhaa/zend/trunk/library/Zend/Db/Select.php(357): Zend_Db_Select->_join('left join', Array, 'leaguesummary.l...', '*', NULL)
#1 /home/assure/bhaa/zend/trunk/application/models/DbTable/LeagueSummary.php(175): Zend_Db_Select->joinLeft(Array, 'leaguesummary.l...')
#2 /home/assure/bhaa/zend/trunk/application/controllers/HousesController.php(110): Model_DbTable_LeagueSummary->getTeamLeagueSummayBySector('20')
#3 /home/assure/bhaa/zend/trunk/library/Zend/Controller/Action.php(513): HousesController->sectorAction()
#4 /home/assure/bhaa/zend/trunk/library/Zend/Controller/Dispatcher/Standard.php(289): Zend_Controller_Action->dispatch('sectorAction')
#5 /home/assure/bhaa/zend/trunk/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#6 /home/assure/bhaa/zend/trunk/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch()
#7 /home/assure/bhaa/zend/trunk/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()

-- 编辑 2 --

所以我添加了第三步,像这样合并两个 union sql 语句

$union = $this->getDefaultAdapter()->select()->union(array($select,$select2));
$logger->info(sprintf(' (%s) ',$union));

这给了我有效的 SQL

2010-06-04T15:11:55+00:00 INFO (6):  (SELECT `team`.`type`, `team`.`id`, `team`.`name` FROM `team` INNER JOIN `company` ON team.parent=company.id WHERE (team.type="C") AND (team.status="ACTIVE") AND (company.sector='20') UNION SELECT `team`.`type`, `team`.`id`, `team`.`name` FROM `team` INNER JOIN `sector` ON team.parent=sector.id WHERE (team.type="S") AND (team.status="ACTIVE") AND (sector.id='20')) 

下一步是将这个 union 子句集成到主查询中,我像这样使用 from() 子句

->from(array('X'=> '('.$union.')' ) )
->joinLeft(array('leaguesummary'=>'leaguesummary'),'leaguesummary.leagueparticipantid=X.id')
->where('leaguesummary.leaguetype="T"')
->where("leaguesummary.leagueid = ?",5)
->order("leaguesummary.leaguedivision asc")
->order("leaguesummary.leagueposition asc")
->limit($limit);
$logger->info(sprintf('%s',$sql));
return $this->getDefaultAdapter()->fetchAll($sql);

但似乎当“$union”变量转换为字符串时,它以某种方式缩短了,这意味着我的 SQL 无效

SELECT `X`.*, `leaguesummary`.* FROM `(SELECT ``team```.```type``, ``team``` AS `X` LEFT JOIN `leaguesummary` ON leaguesummary.leagueparticipantid=X.id WHERE (leaguesummary.leaguetype="T") AND (leaguesummary.leagueid = 5) ORDER BY `leaguesummary`.`leaguedivision` asc, `leaguesummary`.`leagueposition` asc LIMIT 10

有什么想法吗?

最佳答案

对于像您这样“复杂”的查询,您可能不想以“Zend”方式进行查询。您可以将 query() 函数与原始 SQL 一起使用

$rows = $this->getAdapter()->query("
    select t.type, t.tid,t.tname,t.cid,t.cname, ls.*
    from
    (
        select t.type, t.id as tid, t.name as tname, c.id as cid, c.name as cname from team t
        join company c on t.parent=c.id and t.type='C' and c.sector=20 and t.status='ACTIVE'
    union
        select t.type, t.id as tid,t.name as tname, null as cid, null as cname from team t
        join sector s on t.parent=s.id and t.type='S'and s.id=20 and t.status='ACTIVE'
    ) t
    LEFT JOIN leaguesummary ls ON ls.leagueparticipantid=t.tid AND ls.leaguetype='T'
    WHERE ls.leagueid = 5
    ORDER BY ls.leaguedivision asc, ls.leagueposition asc LIMIT 10;  
");

This bug报告显示了 union() 函数的正确用法:

$selectA = $db->select()
    ->from(array('u' => 'user'), 'name')
    ->where('u.id >= 5');

$selectB = $db->select()
    ->from(array('u' => 'user'), 'name')
    ->where('u.id < 5');

$select = $db->select()
    ->union(array($selectA, $selectB));

或者:

$select = $db->select()
    ->union(array(
        $db->select()
            ->from(array('u' => 'user'), 'name')
            ->where('u.id >= 5'),
        $db->select()
            ->from(array('u' => 'user'), 'name')
            ->where('u.id < 5')
));

关于php - Zend_DB union() :Zend_Db_Table_Abstract 与 Zend_Db_Table::getDefaultAdapter(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2967763/

有关php - Zend_DB union() :Zend_Db_Table_Abstract 与 Zend_Db_Table::getDefaultAdapter()的更多相关文章

  1. ruby-on-rails - Railstutorial : db:populate vs. 工厂女孩 - 2

    在railstutorial中,作者为什么选择使用这个(代码list10.25):http://ruby.railstutorial.org/chapters/updating-showing-and-deleting-usersnamespace:dbdodesc"Filldatabasewithsampledata"task:populate=>:environmentdoRake::Task['db:reset'].invokeUser.create!(:name=>"ExampleUser",:email=>"example@railstutorial.org",:passwo

  2. ruby-on-rails - 撤消 "rails generate scaffold"后是否需要撤消 "db:migrate"? - 2

    我是RoR的新手,我正在学习MichaelHartl的教程(所以请随意更正我在您认为合适的地方使用的术语)。在第2章中,我通过运行以下行创建了一个Users表:$railsgeneratescaffoldUsername:stringemail:string$bundleexecrakedb:migrate然后,我运行了下面的代码来尝试创建一个Microposts表(但是,我拼错了没有“r”的Micropost!)...$railsgeneratescaffoldMiropostcontent:stringuser_id:integer$bundleexecrakedb:migrate

  3. ruby-on-rails - 模型范围正在破坏 rake db :migrate - rails 3. 2.3 postgres 9.1.3 - 2

    我在新的Rails应用程序(3.2.3)中运行迁移时遇到了问题。我们正在使用postrgres9.1.3和-pg(0.13.2)-当我运行rakedb:create,然后运行​​rakedb:migrate,我得到->1.9.3-p194(master)rakedb:migrate--trace**Invokedb:migrate(first_time)**Invokeenvironment(first_time)**Executeenvironmentrakeaborted!PG::Error:ERROR:relation"roles"doesnotexistLINE4:WHEREa

  4. ruby-on-rails - 奇数 rake db :migrate output - 2

    为什么rakedb:migrate运行Executedb:schema:dump我的输出全都搞砸了(显示SQL)。看起来像这样:ActiveRecord::SchemaMigrationLoad(0.5ms)SELECT"schema_migrations".*FROM"schema_migrations"(3.7ms)SELECTt2.oid::regclass::textASto_table,a1.attnameAScolumn,a2.attnameASprimary_key,c.connameASname,c.confupdtypeASon_update,c.confdeltyp

  5. ruby-on-rails - Rails 查询 : Filter by properties in another table - 2

    我正在寻找一个清晰的Rails4示例,说明如何根据通过另一个表关联的数据过滤记录。假设我有一个用户模型和一个评论模型。一个用户has_many评论,一个Commentbelongs_to一个用户。评论在其表中也有一个score列。classUserUsers|id|name|email||-----|---------|---------------------||1|"Alice"|"alice@example.com"||2|"Bob"|"bob@example.com"||...|classComment我如何获得所有对内容“k”发表评论且分数>0的用户?请注意,我要返回的是用户

  6. ruby-on-rails - rails 3/ActiveRecord : How to switch/change table name during request dynamically? - 2

    我想在请求期间动态更改ActiveRecord模型类的表名。例如,有许多具有相似结构(列)的表:mydb:sample_data_12222sample_data_12223sample_data_12224sample_data_12225...所以,我想做的是..._1。定义基本模型类,如:classSampleData_2。在请求期间更改目标表,例如:defaction_methodSampleData.set_table_name"sample_data_#{params[:id]}"@rows=SampleData.all如果在非线程环境(如Passenger/mod_rai

  7. ruby-on-rails - 如何在 Prawn 中居中 table ? - 2

    我在prawn中创建了一个表,并希望通过whih传递:position选项,这在手册中也有记录,但它引发了Method_missing错误。好像这个参数不存在了。我怎样才能让Prawn居中? 最佳答案 我遇到了同样的错误。从Github上的master安装解决了这个问题。#Gemfilegem'prawn',git:'https://github.com/prawnpdf/prawn.git'IssuethreadonGithub 关于ruby-on-rails-如何在Prawn中居中t

  8. ruby - 融合表 : Why do I keep getting a "400 Bad Request" error when trying to update a table style via Ruby's RestClient gem - 2

    我正在尝试使用RubygemRestClient为我的一个FusionTables更新样式。这是我的代码:require'rest_client'tableId=''styleId=''key=''table_url="https://www.googleapis.com/fusiontables/v1/tables/#{tableId}/styles/#{styleId}?key=#{key}"update='{"polygonOptions":{"strokeColor":"#ffffff"}}'token='STRINGCONTAININGAUTHORIZATIONTOKEN'R

  9. ruby - Rails 3 db :migrate 的未定义方法 `visitor' - 2

    我在Rails3中进行数据库迁移时遇到异常。undefinedmethod`visitor'for#编辑请查看解决方案here.在我的项目中没有出现字符串visitor所以我很困惑。这是完整的转储:$rakedb:migrate--trace**Invokedb:migrate(first_time)**Invokeenvironment(first_time)**Executeenvironment**Invokedb:load_config(first_time)**Invokerails_env(first_time)**Executerails_env**Executedb:l

  10. ruby-on-rails - rake 数据库 :migrate not working on my postgres db - 2

    好的,所以我有一个Rails应用程序,我试图在postgres数据库上运行迁移,我通常使用mysql,一切都很好,但是当我运行命令时,我得到了这个rakedb:migrate(in/Users/tamer/Sites/my_app)/Users/tamer/.rvm/gems/ruby-1.9.2-p290@my_app/gems/activerecord-3.0.3/lib/active_record/connection_adapters/postgresql_adapter.rb:487:[BUG]Segmentationfaultruby1.9.2p290(2011-07-09

随机推荐