Как использовать множественное предложение в объединении в zend framework 2
Я делаю, как этот sql, в sql-образ zend framework.
SELECT
jobs . *,
c.id AS cid,
c.name AS name,
c.companyImage AS companyImage,
c.logo AS logo,
count(app.userId) AS t_app,
app.applyStatus AS applyStatus,
app.userId AS appUserId
FROM
jobs
LEFT JOIN
companies AS c ON jobs.companyName = c.id
LEFT JOIN
applicants AS app ON jobs.id = app.jobId AND app.applyStatus = 1
WHERE
jobs.ownerId = 16 AND jobs.draftId != 0
GROUP BY jobs.id
ORDER BY jobs.id DESC
LIMIT 3
Для этого sql я уже написал этот код для zend framework 2
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('jobs')
->join(array('c' => 'companies'), 'jobs.companyName = c.id', array('cid' => 'id', 'name', 'companyImage', 'logo'), 'left')
->join(array('app' => 'applicants'), ' jobs.id = app.jobId AND app.applyStatus = 1', array('t_app' => new Expression('count(app.userId)'), 'applyStatus', 'appUserId' => 'userId'), 'left')
->where("jobs.ownerId ={$userId} AND jobs.draftId != 0")
->group('jobs.id')
->order('jobs.id DESC')
->limit(3);
$statement = $sql->getSqlStringForSqlObject($select);
$results = $adapter->query($statement, $adapter::QUERY_MODE_EXECUTE);
но не работает должным образом и дает сообщение, как показано ниже.
SQLSTATE[42S22]: Column not found: 1054 Unknown column '1' in 'on clause'
Ответы
Ответ 1
Проблема заключается в этой части:
app.applyStatus = 1
Рамка экранирует 1, как если бы это было имя столбца, 1
.
Вам нужно также приложить эту часть в выражении
new Expression('jobs.id = app.jobId AND app.applyStatus = 1')
Я думаю, что использование выражений в параметре 'ON' метода join может зависеть от версии ZF2, которую вы используете, я думаю, что она была добавлена 2.1+
Ответ 2
Основываясь на этом ответе. Если вы также хотите, чтобы ваши идентификаторы таблиц и столбцов были экранированы, используйте этот синтаксис:
use Zend\Db\Sql\Expression;
...
$onExpression = new Expression('? = ? AND ? = ?',
['jobs.id', 'app.jobId', 'app.applyStatus', 1],
[Expression::TYPE_IDENTIFIER, Expression::TYPE_IDENTIFIER,
Expression::TYPE_IDENTIFIER, Expression::TYPE_LITERAL]
);
$select->from('jobs')
->join(array('app' => 'applicants'), $onExpression, array('t_app' => new Expression('count(app.userId)'), 'applyStatus', 'appUserId' => 'userId'), 'left');
Конструктор выражения принимает строку, затем аргументы, а затем типы аргументов.
public function __construct($expression = '', $parameters = null, array $types = [])
Ответ 3
Это создаст проблему безопасности. Zf2 изменяет ваш запрос на это:
Select * from tableA inner join tableB
on `tableA`.`column` = `tableB`.`column`
AND `tableB`.`column` = `1`
Он добавляет
`
для каждой части проблем безопасности! Используя new Expression
, вы обходите его, и если вы получаете applyStatus
от входа пользователя, убедитесь в его фильтрации!