add beetween option in $query in yii2 - mysql

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.

Related

Doctrine - SQL Query Builder - update and join?

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

Need help on select statement to be used in laravel

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]);

Doctrine2 DBAL Exists query

I would like to ask for your help with Doctrine2 DBAL query built with QueryBuilder. I'm used to ORM, but I think it's an overkill for such query which is being called in a listener.
I need a query with SELECT EXISTS and I don't know how I can construct it using DBAL QueryBuilder.
I have a subquery already created:
$subQuery = $connection->createQueryBuilder();
$subQuery
->select('o.id')
->from('order', 'o')
->leftJoin('o', 'payment', 'p')
->where($subQuery->expr()->isNull('p.id'))
;
I basically want to check if there are any unpaid orders. I now have no idea how to build the SELECT EXISTS query? Can anyone point me in the right direction? I was thinking about something like this:
$qb->select('EXISTS(?)')->setParameter($subQuery->getDQL())
Will that be the correct solution?
#EDIT
After a while of thinking I decided to use ORM instead. Unfortunately that did not work either, I'm getting an error:
line 0, col 7: Error: Expected known function, got 'EXISTS'
The DQL is:
SELECT EXISTS(<subquery here>)
It is a bit weird considering that It has been build with QueryBuilder:
/* #var $qb QueryBuilder */
$qb = $this->em->createQueryBuilder();
$qb
->select($qb->expr()->exists($subQuery->getDQL()));
A few years late, but you need to specify your EXISTS subquery SQL within the SELECT or WHERE statement portion of the QueryBuilder, as opposed to using a parameter.
Additionally since order is a reserved word in MySQL, you will need to use identifier quotes ` (back-tick) to escape the table name.
When using the ORM; you must specify a FROM statement that references an entity, so you would need to change your approach.
$connection = $this->em->getConnection();
$expr = $connection->getExpressionBuilder();
$qbSub = $connection->createQueryBuilder()
->select('1')
->from('`order`', 'o')
->leftJoin('o', '`payment`', 'p', $expr->eq('p.order_id', 'o.id'))
->where($expr->isNull('p.id'));
/**
* #return string "1" if a record exists, "0" otherwise
*/
$connection->createQueryBuilder()
->select('EXISTS(' . $qbSub->getSQL() . ')')
->execute()
->fetchColumn();
Resulting SQL
SELECT EXISTS(
SELECT 1
FROM `order` AS o
LEFT JOIN `payment` AS p
ON p.order_id = o.id
WHERE p.id IS NULL
);
Note: If you have any parameters, the values for the placeholders must be bound using QueryBuilder::setParameter() on the top-level
query, not the sub-queries.
$qbSub = $connection->createQueryBuilder()
->select('1')
->from('`order`', 'o')
->leftJoin('o', '`payment`', 'p', $expr->andX(
$expr->eq('p.order_id', 'o.id'),
$expr->eq('p.name', ':name') // subquery placeholder
))
->where($expr->isNull('p.id'));
$connection->createQueryBuilder()
->select('EXISTS(' . $qbSub->getSQL() . ')')
->setParameter('name', $value) // subquery placeholder param value
->execute()
->fetchColumn();
However, I suggest changing your query from an exclusion join to an inclusion join with NOT EXISTS. Doing so will filter orders that have been paid, out of your result-set. Instead of attempting to join every order on every payment and retrieve the payments that return null. Dramatically improving the performance of the query.
Example db-fiddle
SELECT EXISTS (
SELECT 1
FROM `order` AS o
WHERE NOT EXISTS(
SELECT NULL
FROM `payment` AS p
WHERE p.order_id = o.id
)
)

codeigniter FIND_IN_SET not working with join

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.

Rails where clause with between not working in mysql

I have the following query in rails...
#registrations = Registration.where(Orientation.where(class_date: #start_date..#end_date))
The query itself does not throw an error, however if I try to inspect #registrations do anything with the variable I get the error...
Cannot visit ActiveRecord::Relation
Any ideas?
Orientation.where(class_date: #start_date..#end_date)
does the range query you like
SELECT * FROM orientations WHERE class_date BETWEEN <start_date> AND <end_date>
UPDATE
Registration.where(created_at: #start_date..#end_date).
joins(:orientation).
where('orientations.created_at' => #start_date..#end_date)
will make the following SQL which I think is what you need
SELECT registrations.* FROM registrations INNER JOIN orientations ON orientations.id = registrations.orientation_id WHERE (registrations.created_at BETWEEN '2014-02-17 16:01:41' AND '2014-02-19 16:01:41') AND (orientations.created_at BETWEEN '2014-02-17 16:01:41' AND '2014-02-19 16:01:41')