I use Doctrine's SQL Query Builder (http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/query-builder.html)
and want to do an update case with a join. I understand that a join is not supported here. So I do this:
$query = $dbalQueryBuilder->update('s_articles_attributes', 'aa')
->set('aa.fp_pos_days', ':days')
->where('aa.articledetailsID IN (SELECT a.id FROM s_articles a WHERE a.supplierID IN (:supplierIds))')
->setParameter('days', $days_string)
->setParameter('supplierIds', $supplierIds)
->execute();
$supplierIds is string(39) "3,4,26,28,31,36,37,38,48,49,55,56,64,82"
When I run this query, nothing happens. When I do this:
$query = $dbalQueryBuilder->update('s_articles_attributes', 'aa')
->set('aa.fp_pos_days', ':days')
->where('aa.articledetailsID IN (SELECT a.id FROM s_articles a WHERE a.supplierID IN (3,4,26,28,31,36,37,38,48,49,55,56,64,82))')
->setParameter('days', $days_string)
->execute();
It works fine. Does anybody know why? And that do I do wrong? I need to use that variable...
I did solve it:
I do pass the values as an array now and critical was to declare the type as well:
->setParameter('days', $days_string)
->setParameter('supplierIds', $supplierIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
try to pass an array and not a string to set parameter doctrine know how to map an "in" where clause.
explode your string
Related
I'm working on a laravel application Where I have two very similar QueryBuilder but producing different result in both conditions.
Query 1:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->whereRaw('feed.active <> agents.feed_status')
->pluck('id');
dd(count($ids)); // print 485236
Query 2:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->where('feed.active', '<>', 'agents.feed_status')
->pluck('id');
dd(count($ids)); // print 4259
I would like to know the key difference between these two QueryBuilder. Why is it producing different results, although it seems identical?
And which query returns the correct result? if I would like to find the records from agents where feed_status is not equel to feed.active.
it seem I have got the clarification. Howevere I would like to share my R&D here. Incase if anyone else got the same problem.
I have printed the raw query and get where() seems consider the third parameter as string compare instead of field compare. That's why seems the result is different.
However when we run the query with whereRaw() it's treated this as table field comparision.
Laravel Code:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->whereRaw('feed.active <> agents.feed_status')
->pluck('id');
MySql Query:
"select * from `agents` left join `feed` on `agents`.`identifier` = `feed`.`identifier` where feed.active <> agents.feed_status"
# where feed.active <> agents.feed_status
Laravel Code:
$ids = $this->model->leftJoin('feed', 'agents.identifier', '=', 'feed.identifier')
->where('feed.active', '<>', 'agents.feed_status')
->pluck('id');
MySql Query:
"select * from `agents` left join `feed` on `agents`.`identifier` = `feed`.`identifier` where `feed`.`active` <> 'agents.feed_status'"
# where feed.active <> 'agents.feed_status'
Yes, the results were meant to be different.
As where method compares a column with a literal value
->where('table.column', 'cond', 'value')
If you are looking to make comparisons in two columns without using whereRaw method; you should instead use whereColumn method
->whereColumn('table1.column1', 'cond', 'table2.column2')
select distinct clientID from Client where clientID not in (select clientID from courseDetails inner join course on coursedetails.courseID = course.courseID where coursedetails.courseID = '$courseID')
If your query is a complex one then you can use RAW query in laravel like:
$data = DB::select(DB::raw('your query'));
Reference
Note: DB::raw() is used to make arbitrary SQL commands which aren't parsed any further by the query builder. They therefore can create a vector for attack via SQL injection.
I give you a starting point:
$results = DB::table('Client')
->whereNotIn('clientID', function($query) use ($courseID) {
$query->select('clientID')
->from('courseDetails')
->join('course', 'courseDetails.courseID', '=', 'course.courseID')
->where('coursedetails.courseID', '=', $courseID);
})->get();
This should get you going. You can tweak it as you want to get your expected result.
Adding to #Mayank answer, you can run raw SQL and pass parameter like this
$result = DB::select('select distinct... where coursedetails.courseID = ? ', [$courseID]);
I want use where in $query
$query->where(['and', "SUM(opportunity_conditions.money)>=10", "SUM(opportunity_conditions.money)<=100"]);
This is my $query :
$query = (new \yii\db\Query())->select(['SUM(opportunity_conditions.money),(opportunity_conditions.money)', 'opportunity.id', 'opportunity.logo', 'profile_details.user_id', 'opportunity.name', 'profile_details.co_name', 'opportunity.address', 'opportunity.project_type_id', 'opportunity.state_id'])->from('opportunity ')->innerJoin('profile_details', 'opportunity.user_id=profile_details.user_id')->where('opportunity_conditions.who=2')->innerJoin('opportunity_conditions', 'opportunity.id=opportunity_conditions.opportunity_id')->addGroupBy('opportunity.id')->orderBy('opportunity.id desc');
I need my query has result where:
SUM(opportunity_conditions.money)>=10 and SUM(opportunity_conditions.money)<=100
This is my error :
SQLSTATE[HY000]: General error: 1111 Invalid use of group function
The SQL being executed was:
SELECT SUM(opportunity_conditions.money),
(opportunity_conditions.money),
opportunity.id,
opportunity.logo,
profile_details.user_id,
opportunity.name,
profile_details.co_name,
opportunity.address,
opportunity.project_type_id,
opportunity.state_id
FROM opportunity
INNER JOIN profile_details
ON opportunity.user_id=profile_details.user_id
INNER JOIN opportunity_conditions
ON opportunity.id=opportunity_conditions.opportunity_id
WHERE
((SUM(opportunity_conditions.id)>=1) AND
(SUM(opportunity_conditions.id)<=1)) AND
(opportunity.id IN (27, 28))
GROUP BY opportunity.id
ORDER BY opportunity.id DESC
Try replacing where() with having(). Then add opportunity_conditions.who to the select() list.
Ok I think you can figure out this way.
first check the query is correct? we can get query from following command
var_dump($query->createCommand()->rawSql);
Now check this query or run this in database, remake the query if you a find mistake.
I have this query with subquery.
SELECT * FROM
(SELECT module_id FROM an_modules AS m LIMIT 20 OFFSET 0) AS m
LEFT JOIN an_module_sites AS ms ON (m.module_id = ms.module_id)
How to use DBAL to build subquery like this?
This doesn't seem to be work.
$qb->select('*')
->from(
$qb->select('module_id')
->from($this->Db->getTableName('modules'), 'm')
, 'm')
->leftJoin('m', $this->Db->getTableName('module_sites'), 'ms', 'm.module_id = ms.module_id');
$stmt = $qb->execute();
$result = $stmt->fetchAll();
I recently needed to do this to implement a pagination/sorting helper. As part of this I would take a querybuilder executed by my model and and generically count the total rows it would produce if unlimited.
To be cross platform I couldn't use rowCount and potential grouping meant I couldn't just change the fields in the select - so the best option was to remove the limits and count it as a subquery. This is what I came up with:
<?php
$totalResults = $qb->getConnection()->createQueryBuilder()
->select('COUNT(*)')
->from(
'('
.$qb
->setFirstResult(null)
->setMaxResults(null)
->resetQueryPart('orderBy')
->getSQL()
.')',
'tmp')
->execute()
->fetch(\PDO::FETCH_COLUMN);
I'm not sure how doctrine ORM handles this, but in pure DBAL at least this seems to work.
I have a codeigniter-mysql requirement to select values from table_2 which joins table_1 and need to apply where statement in a comma separated field value. Tried as follows,
$where = $this->db->escape("FIND_IN_SET(table_1.id,table_2.places_id)<>0");
$this->db->select('table_2.*,GROUP_CONCAT(table_1.location)AS location');
$this->db->from('table_2');
$this->db->join('table_1', $where);
$this->db->where('ltable_2.packages_id', $id);
$results = $this->db->get();
return $results->result();
But the above codeigniter db object returns following mysql query and its not working :(
SELECT `table_2`.*, GROUP_CONCAT(table_1.location)AS location FROM `table_2` JOIN `table_1` ON 'FIND_IN_SET(table_1.id,table_2.places_id)<>0' WHERE `ltable_2`.`packages_id` = <id-goes-here>
It seems the quotes around 'FIND_IN_SET(table_1.id,table_2.places_id)<>0' creates the problem! All helps are appreciated to resolve the issue.
You could try $this->db->join('table_1', $where, false);. That would get rid of the quotes, and if otherwise your query is good, it should be fine.