I use zend framework 2 and I want to create this select:
SELECT
MONTH(created_at) month, COUNT(*)
FROM
requests
GROUP BY
YEAR(created_at), MONTH(created_at)
This is my function I use:
public function statPerMonth() {
$select = $this->tableGateway->getSql()->select();
$select->where(array("created_at > '2017-07-01'"));
$select->columns(array(
'month' => new \Zend\Db\Sql\Expression('MONTH(created_at)'),
'count' => new \Zend\Db\Sql\Expression('COUNT(*)')
));
//$select->group(YEAR(created_at), MONTH(created_at));
$row = $this->tableGateway->selectWith($select);
return $row;
}
How can I realize it?
Thanks for help!
Related
SELECT
t1.post_id, t1.user_id, t1.total_likes, t1.total_comments,
t2.name,
if(t3.user_id, 1, 0) as user_like
FROM `game_posts` as t1
left join users as t2 ON t1.user_id=t2.user_id
left join(
select post_id, user_id from post_likes where user_id=1
)t3
on t1.post_id=t3.post_id
where t1.game_id=1
order by t1.post_id desc
I want to execute this query in zend framework 2, here is my code but i am enable to implement the second join having subquery in it.
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
// MAIN POST TABLE
$select->from(array('t1' => 'game_posts'));
// GET POST USER
$select->join(
array('t2' => 'users'),
new Expression('t1.user_id = t2.user_id'),
array(
"user_name" => "name"
),
'LEFT'
);
$select->where(array("t1.game_id"=>$gameId));
$select->order("post_date DESC");
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($results);
$result = $resultSet->toArray();
return $result;
Basically there are 3 tables game_posts, users and post_likes table,
i am fetching all the posts which has game_id=1 with name of the user who created the post along with the current user flag if he likes the post or not.
Please help me
There is your query :
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select3 = $sql->select();
$select3->columns([post_id, user_id])->from(post_likes)->where(['user_id' => 1]);
$select = $sql->select();
$select->columns(['post_id', 'user_id', 'total_likes', 'total_comments', 'user_like' => new Expression('if(t3.user_id, 1, 0)')])
->from(['t1' => 'game_posts'])
->join(['t2' => 'users'], 't1.user_id=t2.user_id', ['name'], Select::JOIN_LEFT)
->join(['t3' => $select3], 't1.post_id=t3.post_id', [], Select::JOIN_LEFT)
->where(['t1.game_id' => $gameId])
->order('post_date DESC');
This is the content of the global.php file:
return array(
'db' => array(
'driver' => 'Mysqli',
'database' => 'web_builder',
'username' => 'root',
'password' => ''
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
This is the content of my model:
namespace Application\Model;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
class UsersTable extends AbstractTableGateway {
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function user_login($getData,$session_id){ // manage the user's login
$email = $getData['login_email'];
$password = $getData['login_password'];
$select = $this->adapter->query ("select count(*) as counter from users where email = '$email' and password = '".md5($password)."'");
$results = $select->execute();
if ($results->current()['counter'] == 1 ){
$select->getDataSource()->getResource()->closeCursor();
$update_user = $this->adapter->query("UPDATE users SET session_id = '".$session_id."' WHERE email = '".$email."'");
$update_session = $update_user->execute();
return 1;
}else{
return 0;
}
}
}
For some reason the update query is not working. If i commented the count query it works. I observed that i cannot execute multiple queries in the same function for some God know reason :P. I'm getting this message: Statement couldn't be produced with sql: ...... . Both query works perfectly if i executed them in phpmyadmin. Can anyone explain me why this cannot work ? I'm a little desperate :| , I spent severals hours on this
It could be a formatting / preparation issue, taking a look at the manual it suggests the following format to prepare your statement:
$adapter->query('SELECT * FROM `artist` WHERE `id` = ?', array(5));
So in your case try formatting it as so:
$select = $this->adapter->query ('select count(*) as counter from users where email = ? and password = ? ', $email , md5($password) );
I am struggling with Zend now for having the joined table columns in the sql string properly.
I have this code (which works fine):
$expression = new \Zend\Db\Sql\Expression('group = acl_groups.id');
$select = $this->tableGateway->getSql()->select();
$select->columns(array(
$select::SQL_STAR,
'group',
'id',
'status'
))->join('acl_groups', 'group = acl_groups.id');
return $this->tableGateway->selectWith($select);
But I can`t get the acl_groups columns to work.
Any attempt fails. I have read the Zend Documentation and nothing effectively worked for me.
My join table has this columns:
id
name
status
I need name to have an alias "groupname"
I tried this:
$select->columns(array(
$select::SQL_STAR,
'group',
'id',
'status',
array('acl_groups.name' => 'groupname')
)
$select->columns(array(
$select::SQL_STAR,
'group',
'id',
'status',
'acl_groups.name AS groupname'
)
But none works.
You have two ways to do this as mentioned here
Method 1
$resultSet = $tableGateway->select (function (Select $select) {
// now you have `select` object, do whatever you like
});
Method 2
$select = new Select('table_name');
$select->join(
'another_table_name',
'join condition',
array('column of another table name'),
Select::JOIN_INNER
);
$resultSet = $tableGateway->selectWith($select);
I need to add a pagination in this code:
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet;
I tried this example, but I can't do it with the join table.
Anyone can help me?
public function fetchAll($paginated=false)
{
if($paginated) {
// create a new Select object for the table album
$select = $this->getallAlbum();
// create a new result set based on the Album entity
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
// create a new pagination adapter object
$paginatorAdapter = new DbSelect(
// our configured select object
$select,
// the adapter to run it against
$this->tableGateway->getAdapter(),
// the result set to hydrate
$resultSetPrototype
);
$paginator = new Paginator($paginatorAdapter);
return $paginator;
}
$resultSet = $this->tableGateway->select();
return $resultSet;
}
function getallAlbum(){
$sql = new Select();
$sql->from('album')->columns(array('id', 'artist', 'title'))->join('albumcategory', 'album.catId = albumcategory.catId', array('catName' => 'catName'), Select::JOIN_LEFT);
return $sql;
}
Pagination should work fine with joins. This is what I have, similar to an example you provided:
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
return new \Zend\Paginator\Paginator(
new \Zend\Paginator\Adapter\DbSelect(
$select,
$this->tableGateway->getAdapter()
)
);
Please post an exact error that you are getting if the above doesn't work.
Thank you for the answer, but i tried your code, but i had this PDOException message:
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'school_parent_id'
I also tried, to adapat my "join tables" with the example of Rob Allen:
public function fetchAll($paginated=false)
{
if($paginated) {
// create a new Select object for the table album
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
// create a new result set based on the Album entity
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new School());
// create a new pagination adapter object
$paginatorAdapter = new DbSelect(
// our configured select object
$select,
// the adapter to run it against
$this->tableGateway->getAdapter(),
// the result set to hydrate
$resultSetPrototype
);
$paginator = new Paginator($paginatorAdapter);
return $paginator;
}
$resultSet = $this->tableGateway->select();
return $resultSet;
}
But the result is the same.
// create a new Select object for the table album
$select = new \Zend\Db\Sql\Select ;
$select->from('school');
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id');
//change this like the following
// create a new Select object for the table album
$select = $this->yourFunction();
//and define yourFunction like
function youFunction(){
$sql = new Select();
$sql->from('school')->columns(array('schoolid', 'schoolname', 'anotherfield'))->join('school_parent', 'school.school_parent_id= school_parent.school_parent_id', array('schoolName' => 'schoolName'), Select::JOIN_LEFT);
return $sql;
}
Please try the join syntax
$select->from('table1')->join('table2', 'table1 = table2', array('table2.colum_to_return1', 'table2.colum_to_return2'));
Example pagination and sort Url
https://github.com/bigemployee/zf2-tutorial-paginate-sort
Try with another example pagination and sorting
### module_config.php ###
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order]',
'constraints' => array(
'action' => '(?!\bpage\b)(?!\border_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
'page' => '[0-9]+',
'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
'order' => 'ASC|DESC',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
###### AlbumController ###
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Album\Model\Album;
use Album\Form\AlbumForm;
use Zend\Db\Sql\Select;
use Zend\Paginator\Paginator;
use Zend\Paginator\Adapter\Iterator as paginatorIterator;
class AlbumController extends AbstractActionController {
protected $albumTable;
public function indexAction() {
$select = new Select();
$order_by = $this->params()->fromRoute('order_by') ?
$this->params()->fromRoute('order_by') : 'id';
$order = $this->params()->fromRoute('order') ?
$this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
$page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
$albums = $this->getAlbumTable()->fetchAll($select->order($order_by . ' ' . $order));
$itemsPerPage = 10;
$albums->current();
$paginator = new Paginator(new paginatorIterator($albums));
$paginator->setCurrentPageNumber($page)
->setItemCountPerPage($itemsPerPage)
->setPageRange(7);
return new ViewModel(array(
'order_by' => $order_by,
'order' => $order,
'page' => $page,
'paginator' => $paginator,
));
}
}
Add this line to your code:
$select->columns(array(new Expression('DISTINCT school.school_parent_id')));
OR something like this:
$select->join('school_parent','school.school_parent_id = school_parent.school_parent_id', array('sp_id' => 'school_parent_id'));
I'm having trouble doing a basic record update via POST in Laravel.
I have captured all the post data in an array, and if the existing Order# is 0, then I create a new record (works fine). Otherwise I update the existing record.
Order.php
class Order extends Eloquent {
public static $table = 'my_orders';
}
Routes.php
//Handle a new order POST
Route::post('order', array('do' => function() {
$thisOrder = array(
'qty' => Input::get('quantity'),
'desc' => Input::get('description'),
);
$thisOrderID = Input::get('orderNo');
//CHECK FOR NEW OR EXISTING ORDER
if($thisOrderID > 0) {
//THIS FUNCTION SOMEHOW RETURNS THE FUNCTION CALL AND DOESNT CONTINUE PAST
//AND THE RECORD IS NOT UPDATED
$updateOrder = Order::update($thisOrderID, $thisOrder);
}
}
Update:
The code above does in fact work. I had a validation error, which was causing the function to return early.
Instead of this line:
$updateOrder = Order::update($thisOrderID, $thisOrder);
You need to do:
$updateOrder = Order::find($thisOrderID)->update($thisOrder);
With find() (which equals where_id()) you select a specific row from the database and with update you pass the new data.
What do you think of this:
//Handle a new order POST
Route::post('order', array('do' => function() {
$thisOrder = array(
'qty' => Input::get('quantity'),
'desc' => Input::get('description'),
);
$thisOrderID = Input::get('orderNo');
$order = Order::find( $thisOrderID );
//CHECK FOR NEW OR EXISTING ORDER
if( $order ) {
$order->title = 'New order title';
$order->desc = 'New description';
$order->save();
}
}
erm , I will suggest to do it this way, if $thisOrder include the key, it will just update the record, else it will just create a new record.
$thisOrder = array(
'orderNo' => Input::get('orderNo'),
'qty' => Input::get('quantity'),
'desc' => Input::get('description'),
);
$updateOrder = Order::save($thisOrder);
if Input::get('orderNo') no value will be create else update