我正在尝试使用Zend Framework构建一个社交网络。然而,最近我很难将一些复杂的SQL查询转换为Zend语言。例如:
"SELECT t.plural_name, p.name as users_name, u.ID
FROM users u, profile p, relationships r, relationship_types t
WHERE t.ID=r.type
AND r.accepted=1
AND (r.usera={$user} OR r.userb={$user})
AND IF( r.usera={$user},u.ID=r.userb,u.ID=r.usera)
AND p.user_id=u.ID"
如何使用Zend的select()对象执行此查询?非常感谢!
每当我有复杂的查询需要处理时,我通常会尝试在MySQL中运行它们。一旦我找到了确切的SQL语句,我就开始将其"翻译"为Zend。我看起来有点复杂,但从长远来看,你可以马上在赞德做这些。以下是我对它的分解。首先弄清楚SQL语句是什么:
SELECT t.plural_name, p.name as users_name, u.ID
FROM users u, profile p, relationships r, relationship_types t
WHERE t.ID=r.type AND r.accepted=1 AND
(r.usera={$user} OR r.userb={$user}) AND
IF( r.usera={$user},u.ID=r.userb,u.ID=r.usera) AND
p.user_id=u.ID
现在,您需要将所有关系转换为联接。连接一开始有点可怕,但这只是一种将表及其连接到另一个表的标准放在一行中的方法。
SELECT t.plural_name, p.name AS users_name, u.ID
FROM users u
INNER JOIN profile AS p ON p.user_id = u.ID
INNER JOIN relationships AS r ON IF(r.usera={$user}, u.ID=r.userb, u.ID=r.usera)
INNER JOIN relationship_types AS t ON t.ID = r.type
WHERE
(r.usera={$user} OR r.userb={$user}) AND
r.accepted=1
现在它是以一种更"Zend友好"的方式编写的,您可以很容易地开始将其转换为Zend:
$select = $this->select()->setIntegrityCheck(false);
$select->from(array('u'=>'users'), '');
$select->join(array('p'=>'profile'), 'p.user_id = u.ID', '');
$select->join(array('r'=>'relationships'), 'IF(r.usera={$user}, u.ID=r.userb, u.ID=r.usera)', '');
$select->join(array('t'=>'relationship_types'), 't.ID = r.type', '');
$select->columns(array(
't.plural_name',
'users_name'=>'p.name',
'u.ID'));
$select->where('r.usera={$user}');
$select->orWhere('r.userb={$user}');
$select->where('r.accepted=1');
这样就可以了。
您可以将其作为示例:(尽管它并不完整)
<?php
$this->_query = $this->_DB->select()->from(array('u'=>'users'),array('(u.ID)'))
->join(array('p'=>'profile'),
'p.user_id = u.ID',
'p.name AS users_name')
->join(array('r'=>'relationships'),
'r.userb = u.ID')
->join(array('t'=>'relationship_types'),
't.ID = r.type',
't.plural_name')
->where('t.ID = r.type AND r.accepted = 1')
->where('r.usera = :user')
->orWhere('r.userb = :user')
->bind(array('user'=>$user));
对于真正复杂的查询,只使用SQL可能更容易。重要的是,进入查询的所有参数都要正确转义,以防止SQL注入。