Propel ORM: Order By FIELD - propel

I'm trying to do a query with a custom "order by" with Propel 1.6
select * from myObject ORDER BY FIELD(id, 3, 11, 7, 1)
this does not work:
myObjectQuery::create()
->orderById($someIds)
->find()
how can i do?

$ids = array(3, 11, 7, 1);
$cids = implode(',', $ids);
myObjectQuery::create()
->addAscendingOrderByColumn("FIELD (tableName.id, {$cids})")
->find()

you can stack order-by's in order that you want:
myObjectQuery::create()
->orderByField1
->orderbyField3('desc')
->orderbyField2
->find()
Try that.
Update 2:
$con = Propel::getConnection();
$query = 'SELECT COUNT(t1.user) AS users, t1.choice AS lft, t2.choice AS rgt
FROM choice t1 iNNER JOIN choice t2 ON (t1.user = t2.user)
WHERE t1.choice IN (?, ?) AND t2.choice IN (?, ?)
GROUP BY t1.choice, t2.choice';
$stmt = $con->prepare($query);
$stmt->bindValue(1, 'foo');
$stmt->bindValue(2, 'bar');
$stmt->bindValue(3, 'baz');
$stmt->bindValue(4, 'foz');
$res = $stmt->execute();
in your case, I would establish $con, create a query to get your value list, then use a for loop to assign your $stmt->bindValue(#,#) and then execute.

$ids = array(3, 11, 7, 1);
$cids = implode(',', $ids);
myObjectQuery::create()
->orderBy("FIELD(id, {$cids})")
->find()

Related

Laravel 5.6: how to create a subquery using Query Builder

I would like to reproduce following mySQL query using Laravel query builder:
*SELECT SUM(scores) FROM (SELECT scores FROM player_games WHERE player_id = 1 ORDER BY id DESC LIMIT 2) scores
Any suggestions?
Here the solution:
$sub = playerGame::where('player_id',1)->where('scores','>',0)->limit(2)->orderBy('id','desc');
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") )
->mergeBindings($sub->getQuery())
->sum('scores');
return $count;
Use fromSub():
$sub = playerGame::select('scores')
->where('player_id', 1)
->where('scores', '>', 0)
->limit(2)
->orderBy('id','desc');
$sum = DB::query()->fromSub($sub, 'scores')->sum('scores');
$responce= DB::table('player_games')->where('player_id',1)->sum('amount');
dd(collect($responce)->sortByDesc('id')->take(2));
please cheack this one.....i try it's work....and add use DB;in the top of controller....

Covert MySql query to Laravel

Can you please help me out to write the Laravel Raw Query for below Mysql query.
SELECT
SUM(IF(d.business_email_template_10_open = "Yes", 1,0)) AS `business_email_template_10_open`,
SUM(IF(d.business_email_template_11_open = "Yes", 1,0)) AS `business_email_template_11_open`
FROM dummy_email_track d
join recommend_email_send_by_cron r on d.user_id = r.user_id
join user_form_submission u on r.user_id = u.id'
where d.business_id = $businessId
If you can't use stored procedure, ignore my answer.
I think you can't use Laravel QueryBuilder cause something reason(I have a similar situation). How about using SP(stored procedure)?
Mysql SP
CREATE DEFINER=`your_mysql_id`#`%` PROCEDURE `get_usage_business_email_template`()
__SP:BEGIN
BEGIN
SELECT
SUM(IF(d.business_email_template_10_open = "Yes", 1,0)) AS `business_email_template_10_open`,
SUM(IF(d.business_email_template_11_open = "Yes", 1,0)) AS `business_email_template_11_open`
FROM dummy_email_track d
join recommend_email_send_by_cron r on d.user_id = r.user_id
join user_form_submission u on r.user_id = u.id'
WHERE d.business_id = $businessId
END;
END
And, Laravel call this SP like below
$result = DB::select('CALL get_usage_business_email_template()');
I hope you will save your time becasue my answer...
This should give you a headstart!
https://laravel.com/docs/5.6/database#running-queries
$results = DB::select('select * from users where id = :id', ['id' => 1]);
Make sure you give right id to your where clause. So in you case it would something like this:
(where d.business_id = :businessId, ['businessId' => 1])
Goodluck!
Please try this :
$data = DB::table('dummy_email_track as d')
->select('d.*','r.*','u.*')
->selectRaw('SUM(IF(d.business_email_template_10_open = "Yes", 1,0)) AS business_email_template_10_open')
->selectRaw('SUM(IF(d.business_email_template_11_open = "Yes", 1,0)) AS `business_email_template_11_open`')
->leftJoin('recommend_email_send_by_cron as r','d.user_id', '=', 'r.user_id')
->leftJoin('user_form_submission as u', 'r.user_id', '=', 'u.id')
->where('d.business_id','=', $businessId)
->get();

Doctrine create subquery with bound params

I am trying to construct a query that will basically pull all entries whose id's have 2 particular entries in another table so I am trying the below:
$query = $this->createQuery('e');
$subquery1 = $query->createSubquery('sea')
->select('sea.entry_id')
->from('Table sea')
->addWhere('sea.form_element_id = ?', $element)
->addWhere('sea.answer = ?', $answer)
->getDQL();
$subquery2 = $query->createSubquery('sea2')
->select('sea2.entry_id')
->from('Table sea2')
->addwhere('sea2.form_element_id = ?', $element2)
->addWhere('sea2.answer = ?', $answer2)
->getDQL();
$query->addWhere('e.id IN ?', $subquery1)
->addWhere('e.id IN ?', $subquery2);
return $query->execute();
However this is gives me an error on bound params.
What is the correct ways of constructing such subqueries?
NOTE that if I dont bind the params in the subqueries it works fine.
$nestedQuery = " id IN (SELECT sea.entry_id from table sea where sea.form_element_id = ? and sea.answer = ?) "
. " and id IN (SELECT sea2.entry_id from table sea2 where sea2.form_element_id = ? and sea2.answer = ?)";
return $this->findBySql($nestedQuery, array($param1, $param2, $param3, $param4));
That obviously returns a doctrine collection but you can do getFirst or loop through the returned objects or even use the Hydrator to get an array!

How to use IN/AND clause in Yii framework?

I have a MySQL table with 3 columns: ID, name, user.
I wish to use the following SQL with Yii framework:
$sql = "SELECT * FROM my_table WHERE idName=".$name." AND user IN .$arrayOfUsers;
// $arrayOfUsers is an array of int [0]->1, etc.
I tried in three different ways, but without success:
1)
$sql = "SELECT * FROM my_table WHERE idName=".$name." AND user IN .$arrayOfUsers;
$command = $connection->createCommand($sql);
$dataReader = $command->query();
$query = $dataReader->readAll();
The error is:
PHP Error [8]
Array to string conversion
2)
$query = Yii::app()->db->createCommand()
->select('*')
->from('my_table')
->where(array('and', array('in', 'user', $arrayOfUsers), array('idName' => $name)))
->queryAll();
The error is:
PHP Error [8]
Undefined offset: 0
3)
$query = Yii::app()->db->createCommand()
->select('*')
->from('my_table')
->where(array('and', array('in', 'user', $arrayOfUsers), 'idName='.$name)))
->queryAll();
The error is:
CDbException CDbCommand failed to execute the SQL
statement: SQLSTATE[42000]: Syntax error or access violation: 1064 You
have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near 'idName=7)'
at line 3. The SQL statement executed was: SELECT * FROM
my_table WHERE (user IN ('1', '2', '3', '4')) AND
(idName=7)
There has many ways to do but I'd like to use Active Record to handle this thing.
However, your question was around Query Builder, I give you correct one
Edited: (As your comment, idName is big INT instead of var char)
1) You got error because you pass $arrayOfUsers which was array, not expected string on your sql. It should be
$connection=Yii::app()->db;
$sql = "SELECT * FROM my_table WHERE idName=".$name." AND (user IN(".implode(',',$arrayOfUsers)."))";
$command = $connection->createCommand($sql);
$query = $command->queryAll();
2) Using Query builder and where operator
$query = Yii::app()->db->createCommand()
->select('*')
->from('my_table')
->where(array('in', 'user', $arrayOfUsers))
->andwhere('name = :name', array('idName'=>$name))
->queryAll();
3) If you want to wrap them together, it'll be fine, but they look unsightly like this
$query = Yii::app()->db->createCommand()
->select('*')
->from('my_table')
->where(array('and', 'idName= ' . $name, array('in', 'user', $arrayOfUsers)))
->queryAll();
More references how to use where operator from official document
// WHERE id=1 or id=2
where('id=1 or id=2')
// WHERE id=:id1 or id=:id2
where('id=:id1 or id=:id2', array(':id1'=>1, ':id2'=>2))
// WHERE id=1 OR id=2
where(array('or', 'id=1', 'id=2'))
// WHERE id=1 AND (type=2 OR type=3)
where(array('and', 'id=1', array('or', 'type=2', 'type=3')))
// WHERE `id` IN (1, 2)
where(array('in', 'id', array(1, 2))
// WHERE `id` NOT IN (1, 2)
where(array('not in', 'id', array(1,2)))
// WHERE `name` LIKE '%Qiang%'
where(array('like', 'name', '%Qiang%'))
// WHERE `name` LIKE '%Qiang' AND `name` LIKE '%Xue'
where(array('like', 'name', array('%Qiang', '%Xue')))
// WHERE `name` LIKE '%Qiang' OR `name` LIKE '%Xue'
where(array('or like', 'name', array('%Qiang', '%Xue')))
// WHERE `name` NOT LIKE '%Qiang%'
where(array('not like', 'name', '%Qiang%'))
// WHERE `name` NOT LIKE '%Qiang%' OR `name` NOT LIKE '%Xue%'
where(array('or not like', 'name', array('%Qiang%', '%Xue%')))
http://www.yiiframework.com/doc/guide/1.1/en/database.query-builder
Try this
$criteria = new CDbCriteria();
$criteria->select = "*";
$criteria->condition = "idname = :name ";
$criteria->params = array (
':name' => $name,
);
$criteria->addInCondition('user', $arrayOfUsers);
my_table::model()->findAll($criteria);

Insert multiple rows using a single query

Can Joomla's DB object add multiple rows at once? MySQL can do this like so:
INSERT INTO x (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
But can Joomla's own functions achieve the same thing in a single query? Currently I am doing a loop to insert each row (same table) in separate query. Not a good idea when dealing with tons of rows at once.
In your model you can do this:
$db = $this->getDBO();
$query = "
INSERT INTO x (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
";
$db->setQuery($query);
$db->query();
If you are outside your model you need to get the DB object like so:
$db = JFactory::getDBO();
You can use:
$db = JFactory::getDbo();
$query = $db->getQuery(true); // !important, true for every new query
$query->insert('#__table_name'); // #__table_name = databse prefix + table name
$query->set('`1`="one"');
$query->set('`2`="two"');
$query->set('`3`="three"');
/* or something like this:
$query->columns('`1`,`2`,`3`');
$query->values('"one","two","three"');
*/
$db->setQuery($query);
$db->query();
and $db->insertId() can return you autoinc id if you have one.
Try this, if you have values in an array :
$query = $this->db->getQuery(true);
$query->insert($this->db->quoteName('#__table_name'));
$query->columns($this->db->quoteName(array('col_1','col_2','col_3','col_4')));
for($i=0; $i < lengthOfArray; $i++)
{
$values= $arr_1[$i].','.$this->db->quote($arr_2[$i]).','.$this->db->quote($arr_3[$i]).','. $arr_4[$i];
$query->values($values);
}
$this->db->setQuery($query);
$result = $this->db->query();
You don't need $db = $this->getDBO();
just use this:-
$query = "
INSERT INTO x (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
";
$this->_db->setQuery($query);
$this->_db->query();
Try this:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->insert('x');
$query->columns('a,b');
$query->values('1', 'one');
$query->values('2', 'two');
$query->values('3', 'three');
$db->setQuery($query);
$db->query();
A description of "values" method
Adds a tuple, or array of tuples that would be used as values for an INSERT INTO statement.
Usage:
$query->values('1,2,3')->values('4,5,6');
$query->values(array('1,2,3', '4,5,6'));
In latest version of Joomla!, you can use it's own DB class as follows. Remember to use 'quoteName()' and 'quote()' functions as you needed.
$dbo = JFactory::getDbo();
$query = $dbo->getQuery(true);
$columns = array('col_one','col_two', 'col_three');
$values = array();
//if you need, here you can use forloop/foreach loop to populate the array
$values[] = 'val_1, val_2, val_3'; // first row values
$values[] = 'val_4, val_5, val_6'; // second row values
...
$query->insert($dbo->quoteName('#__table_name'));
$query->columns($columns);
$query->values($values);
$dbo->setQuery($query);
$dbo->query();
Hope this saves your time. Thanks. Happy coding! :)
...
$columns = array('user_id', 'type', 'object', 'lvl', 'date');
$values = array();
foreach ($batch as $row) {
$array = array(
$row->user_id,
$db->quote($row->type),
$db->quote($row->object),
$db->quote($row->lvl),
$db->quote($row->date),
);
$values[] = implode(',', $array);
}
$query->insert($db->quoteName('#activity_log'));
$query->columns($db->quoteName($columns));
$query->values($values);
$db->setQuery($query);
$result = $db->execute();

Resources