Rewrite SQL in cakephp3? - cakephp-3.0

This is my query in for MySQL:
select u.full_name, c.comment_content from users u, comments WHERE u.user_id=c.user_id
How do I have rewrite this SQL using find() in cakephp?

Here You go:
$query = $this->Users
->find()
->select(['full_name', 'comment_content'])
->where(['user_id =' => $cUserID])
->order(['created' => 'DESC']); //extra
http://book.cakephp.org/3.0/en/orm/query-builder.html

Related

laravel query building with a lot of joins

my sql query is
$q = "SELECT
file,
roleId,
page,
type,
userType,
COUNT(DISTINCT($a)) as 'a',
COUNT(DISTINCT($b)) as 'b'
FROM table_name
WHERE
course IN ($type)
AND date BETWEEN '$startDate' AND '$endDate'
AND (course_1 is NULL OR course_1 NOT IN ('ABCD'))
AND deleted IS NULL
AND type LIKE '%Professor%'
AND action = 'submit'
GROUP BY file, roleId";
I want to convert that query into laravel query builder like
$orders = DB::table('table_name')
->select('file', 'roleId', 'page', 'type', userType DB::raw('COUNT(DISTINCT(($a)) as 'a'))
->groupBy('file', 'roleId')
->get();
Do understand how to add the other COUNT into it and how and where to chain the ->where() ?
<?php
$orders = DB::table('table_name')
->whereIn('course', $courseTypes)
->whereBetween('date', [$startDate, $endDate])
->where(function($q){
return $q->whereNull('course_1')
->orWhereNotIn('course_1', $courseArrayToFilter);
})
->whereNull('deleted')
->where('type', 'like', '%Professor%')
->where('action', 'submit')
->groupBy('file', 'roleId')
->select(
'file',
'roleId',
'page',
'type',
'userType',
\DB::raw("COUNT(DISTINCT($a)) as a"),
\DB::raw("COUNT(DISTINCT($b) as b")
)
->get();
Maybe in a cleanest way doing this:
Use the Model instance in inspite of invoke the DB facade
Use whereRaw to pass complex or pure SQL queries
Use selectRaw() to process pure SQL queries for instance functions like COUNT
Use Multiple WHERE to emulate AND operator
Use whereIn to filter ranges of data
You need to GROUP BY all columns in your SELECT you have an error at this point, I mean your query is wrong
Code
$data = Model::select('file', 'roleId', 'page', 'type', 'userType')
->selectRaw('COUNT(DISTINCT($a)) as a')
->selectRaw('COUNT(DISTINCT($b)) as b')
->whereRaw('type IN $type')
->whereIn('date', [$startDate, $endDate])
->whereRaw("course_1 IS NULL OR course_1 NOT IN('ABCD')")
->whereNull('deleted')
->where('type', 'LIKE', "%".'Professor'."%")
->where('action', '=', 'submit')
->groupBy('file', 'roleId', 'page', 'type', 'userType')
->get();

Left Join from Select Zend Framework

How can I do a Query like this using the Zend framework
SELECT * FROM `productos` AS `p`
LEFT JOIN (SELECT SUM(cantidad) AS transferencias FROM transferencias WHERE upc = p`.`upc` and sucursal = 10)
AS `trans` ON trans.upc = p.upc AND trans.sucursal_clave_destino = 10
Thank you in advance.
You need to try this one.
I can't try it but the way of resolve it you can use from my query
$this->getAdapter()
->select()
->from(array('p' => 'productos'))
->joinLeft(array('trans' => $this->getAdapter()
->select()
->from('transferencias', 'SUM(cantidad)')
->where('upc IN (?)', $this->getAdapter()
->select()
->from('productos', 'upc')
)->where('sucursal = ?', 10)
), 'trans.upc = p.upc')
->where('trans.sucursal_clave_destino = ?', 10)
->query()
->fetchAll();
First of all, I'm afraid it's impossible for your query to run because the syntax is wrong. The correct way to write it is:
SELECT *, SUM(trans.cantidad) as cantidad
FROM productos AS p
LEFT JOIN transferencias AS trans
ON p.upc = trans.upc
WHERE trans.sucursal_clave_destino = 10 AND trans.sucursal = 10
First approach
I assume you have created your model in this manner: http://framework.zend.com/manual/1.12/en/learning.quickstart.create-model.html
For example, in your Default_Model_ProductosMapper:
function getXXXX(){
$select = "[THE ABOVE QUERY]";
$result = $this->getDbTable()->getAdapter()->fetchAll($select);
return $result;
}
This is the most basic approach.
Second approach
By using Zend_Db functions, which is like prepare statement in database concept. Only use it to increase safety if you are passing parameters from user input (see SQL injection), otherwise it's safe to use the first approach.
Still, in your mapper:
function getXXXX(){
$query = $this->getDbTable()->getAdapter()->select();
$query->from('productos', array());
$query->joinLeft('transferencias', 'productos.upc = transferencias.upc', array('SUM(trans.cantidad) as cantidad));
$query->where("trans.sucursal_clave_destino = 10");
$query->where("trans.sucursal = 10");
// get result
$stmt = $this->getDbTable()->getAdapter()->query($query);
$result = $stmt->fetchAll();
return $result;
}
Third approach
If you are using Database ORM like Doctrine2, you can also write SQL or DQL (Doctrine Query Language) queries, which syntax is highly similar with SQL queries but absolutely NOT the same mechanism. The document is here. This document covers both approaches above for DQL and also will tell you where to put them.

I am trying to replace :search when the query is executed but it does not seem to be replaced

After reviewing this SO, I am having some trouble using prepared statements.
I have added the following to my db connection:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
And here are my query statements:
$query = "SELECT schedules.schedule_name, users.name, schedules.schedule_id
FROM schedules
INNER JOIN users
ON schedules.admin_id=users.user_id
WHERE schedules.schedule_name
LIKE '%:search%'
ORDER BY schedules.schedule_name";
$stmt = $db->prepare($query);
$result = $stmt->execute(array('search' => $search_string));
$search_results = $stmt->fetchAll();
As you can see in the LIKE, I am trying to replace :search when the query is executed but it does not seem to be replaced.
When you do a parameterized query, it is not simply a string replace, and you don't surround it with singlequotes:
$query = "SELECT schedules.schedule_name, users.name, schedules.schedule_id
FROM schedules
INNER JOIN users
ON schedules.admin_id=users.user_id
WHERE schedules.schedule_name
LIKE :search
ORDER BY schedules.schedule_name";
But you want to have % wildcards around the term right? Add them when you inject it:
$result = $stmt->execute(array('search' => '%' . $search_string . '%' ));

How to run raw SQL Query with Zend Framework 2

Is there a way to execute a SQL String as a query in Zend Framework 2?
I have a string like that:
$sql = "SELECT * FROM testTable WHERE myColumn = 5"
now I want to execute this string directly.
Just pass the sql string to your db adapter like this:
$resultSet = $adapter->query($sql, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
And if you want to pass parameters:
$sql = "SELECT * FROM testTable WHERE myColumn = ?";
$resultSet = $adapter->query($sql, array(5));
EDIT: Please note that the query method does not always returns a resultset. When its a resultset producing query(SELECT) it returns a \Zend\Db\ResultSet\ResultSet otherwise(INSERT, UPDATE, DELETE, ...) it will return a \Zend\Db\Adapter\Driver\ResultInterface.
And when you leave the second Parameter empty you will get a \Zend\Db\Adapter\Driver\StatementInterface which you can execute.
use Zend\Db\Sql\Sql;
use Zend\Db\Adapter\Adapter;
$dbAdapterConfig = array(
'driver' => 'Mysqli',
'database' => 'dbname',
'username' => 'dbusername',
'password' => 'dbuserpassword'
);
$dbAdapter = new Adapter($dbAdapterConfig);
$sql = new Sql($dbAdapter);
$select = $sql->select();
$select->from('testTable');
$select->where(array('myColumn' => 5));
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
S. docu: Zend\Db → Zend\Db\Sql
If you are using tableGateway, you can run your raw SQL query using this statement,
$this->tableGateway->getAdapter()->driver->getConnection()->execute($sql);
where $sql pertains to your raw query. This can be useful for queries that do not have native ZF2 counterpart like TRUNCATE / INSERT SELECT statements.
If you have EntityManager $em on your hands, you can do something like this:
$select = $em->getConnection()->executeQuery("
SELECT a.id, a.title, a.announcement, asvc.service_id, COUNT(*) AS cnt,
GROUP_CONCAT(asvc.service_id SEPARATOR \", \") AS svc_ids
FROM article AS a
JOIN articles_services AS asvc ON asvc.article_id = a.id
WHERE
asvc.service_id IN (
SELECT tsvc.service_id
FROM tender AS t
JOIN tenders_services AS tsvc ON tsvc.tender_id = t.id
WHERE t.id = :tenderId
)
GROUP BY a.id
ORDER BY cnt DESC, a.id DESC
LIMIT :articlesCount
", [
'articlesCount' => 5,
'tenderId' => $tenderId,
], [
'articlesCount' => \PDO::PARAM_INT,
]);
$result = $select->fetchAll(); // <-- here are array of wanted rows
I think this way to execute complex queries is best for Zend. But may be I'm not very smart in Zend still. Will glad to see if it helps to someone.

How use LIKE in Yii query builder

How build this query with YIi query builder
SELECT *
FROM `table`
WHERE type_item = 2 AND name_item LIke '%name%'
I tried so
return Yii::app()->db->createCommand()
->select('*')
->from('{{event_field_variants}}')
->where('type_item = :type AND name_item LIKE "%:substr%"', array(':type' => '2', ':substr' => 'name'))
->order('variant ASC')
->queryAll();
But this query get CdbcException.
On Yii documentation are examples only with like or only with simple param.
->where('name_item LIKE :substr', array(':substr' => '%name%'))
Just put it in the variables part?