Laravel query with temporary table - php

How to convert this query to laravel db query.
SELECT * FROM {
Select * from organizers
Order by organizers.rank
} Group by t.department
This is simplified version of query. In real the inner query has more where clause and built using laravel db query.
Edit: I am aware of raw query. But that's not what I am looking for. Inner query is complex and has lots of conditional where clause. I would like to retain the db query object I used there.

You can have 2 different query builders and merge their binding like below :
$innerQuery = DB::table('organizers')->orderBy('organizers.rank');
$mainQuery = DB::table(DB::raw('(' . $innerQuery->toSql() . ') as t'))
->mergeBindings($innerQuery->getQuery())
->groupBy('t.department')
->get();
This will also help you retail the $innerQuery builder instance for your later use as you have mentioned in the question.

I think you will have to execute a raw query.
$result = DB::select("SELECT * FROM (
Select * from organizers
Order by organizers.rank
) Group by t.department");
reference: https://laravel.com/docs/5.7/queries#raw-expressions

Related

What is the best way to handle this sub query in laravel using DB:raw?

After several attempts I am having trouble getting this raw query formatted using DB::raw in laravel. Could someone point me in the right direction? I am trying to avoid using DB::table or spliting it up into multiple queries if possible.
select id
from ParticipantDetail
where testId= (
select testId from PacketDetail where PacketDetail.packetid=ParticipantDetail.packetid and [order]='1'
)
and packetid = (
select packetid from ParticipantDetail where id = '1f4716e9-6e8b-41ce-b746-60a013fab38f'
)
and masterid = (
select masterid from ParticipantDetail where id = '1f4716e9-6e8b-41ce-b746-60a013fab38f'
)
I think there is no need to make these sub-queries
I changed the query a little bit. and used DB::select() to run it.
DB::select("select partDtl.id from ParticipantDetail partDtl
INNER JOIN PacketDetail packDtl on packDtl.packetid = partDtl.packetid
WHERE partDtl.id = ? and packDtl.order = ?",
['1f4716e9-6e8b-41ce-b746-60a013fab38f', '1']);
I hope it will work.

Symfony queryBuilder, can`t rewrite sql to queryBuidler

I can`t rewrite SQL query to queryBuilder, for my task need only queryBuilder object.
I have this SQL query, I need take from database per each user, orders which be last and have isPaid = 0.
SELECT
*
FROM
orders o
JOIN
(
SELECT
owner_id,
MAX(created_at) max_date
FROM
orders
GROUP BY
owner_id
) max_dates
ON
o.owner_id = max_dates.owner_id AND o.created_at = max_dates.max_date
WHERE
is_paid = 0
Since you join a subquery it might be a bit tricky to transfer this SQL query to DQL. Fortunately, you don't have to. Doctrine ORM allows you to perform a regular SQL query and then map the results back to an object, just like it would with DQL.
You can have a look at Native Queries and ResultSetMapping for this:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/native-sql.html
In your case it could look something roughly like this in a repository find-method:
public function findLatestUnpaidOrders()
{
$sql = '...'; // Your query
$rsm = new ResultSetMappingBuilder($this->em);
$rsm->addRootEntityFromClassMetadata(Order::class, 'order');
$query = $this->em->createNativeQuery($sql, $rsm);
// $query->setParameter('owner_id', $user->getId()); // if you later want to pass parameters into your SQL query
return $query->getResult();
}

Cross Join with php codeigniter query

Is there away to cross join from php. In example:
Currently I query a database like so:
$company_id = 20;
$templates_data = $this->db->select('template_id')
->from('dr_template_relational')
->where('dr_template_relational.company_id',$company_id)
->get()
->result_array();
What I'm looking to do is something like this:
->from('dr_template_relational')
->cross_join()
There's several responses to this question on SO but post reference a regular sql query like so:
"SELECT * FROM citys LEFT JOIN comments ON comments.city=citys.city WHERE citys.id=$id";
This would be the way to do it in SQL query but the point here is to do it in php and get the data returned with a cross join. I also realize the query can be made with in php to have it select the data and join it with code but my question is related to is there away to simply add ->cross_join() or something like that.
You can run raw query in codeigniter to solve your problem as below:
$sql 'your query here with cross join';
$query = $this->db->query($sql);
return $query->result_array();
Hope it helps you :)
You can use CI join method.
$company_id = 20;
$templates_data = $this->db->select('dr_template_relational.template_id')
->where('dr_template_relational.company_id',$company_id)
->join('table','dr_template_relational.company_id=table.company_id','LEFT')
->get()
->result_array();
where 'LEFT' is the join type

How to convert mysql query to codeigniter using query builder?

The following is my mysql query:
select * from db_posts LEFT JOIN db_followers ON db_posts_user_id = db_followers_following AND db_followers_user_id = 276
How can I convert it to codeigniter using query builder?
$this->db->where('db_posts_user_id', 'db_followers_following');
$this->db->where('db_followers_user_id', 276);
$this->db->order_by('db_posts.db_posts_id', 'DESC');
$this->db->join('db_followers', 'db_followers.db_followers_following = db_posts.db_posts_user_id');
$query2 = $this->db->get('db_posts')->result_array();
I get the required result when I use mysql query. But I get a blank array when I use codeigniter queries. What is wrong in my CI Query?
why are you using those where clause? if you are using it as condition for your 'JOIN' process, try it like this:
$this->db->order_by('db_posts.db_posts_id', 'DESC');
$this->db->join('db_followers', 'db_followers.db_followers_following = db_posts.db_posts_user_id and db_followers_user_id = 276', 'left');
$query2 = $this->db->get('db_posts')->result_array();
Points to Note
1)as previous comments said, you should 'Left Join' if you want to get all posts from 'db_posts'.
2) You can add Multiple conditions in ON Clause using and but within ''. all your conditions should be specified before second comma(,) which is before mentioning 'LEFT'.
Hope this will help. Lemme know if this help
Try adding the "Left" option to tell it what kind of join to do:
$this->db->join('db_followers', 'db_followers.db_followers_following = db_posts.db_posts_user_id', 'Left');
Also I'm not sure you need
$this->db->where('db_posts_user_id', 'db_followers_following');
this is already covered by your JOIN statement.
Source:
http://www.bsourcecode.com/codeigniter/codeigniter-join-query/#left-join and https://www.codeigniter.com/userguide3/database/query_builder.html

Join subquery with doctrine 2 DBAL

I'm refactoring a Zend Framework 2 application to use doctrine 2.5 DBAL instead of Zend_DB (ZF1). I have the following Zend_Db query:
$subSelect = $db->select()
->from('user_survey_status_entries', array('userSurveyID', 'timestamp' => 'MIN(timestamp)'))
->where('status = ?', UserSurveyStatus::ACCESSED)
->group('userSurveyID');
$select = $db->select()
// $selectColNames contains columns both from the main query and
// the subquery (e.g. firstAccess.timestamp AS dateFirstAccess).
->from(array('us' => 'user_surveys'), $selectColNames)
->joinLeft(array('firstAccess' => $subSelect), 'us.userSurveyID = firstAccess.userSurveyID', array())
->where('us.surveyID = ?', $surveyID);
This results in the following MySQL query:
SELECT `us`.`userSurveyID`,
// More columns from main query `us`
`firstAccess`.`timestamp` AS `dateFirstAccess`
FROM `user_surveys` AS `us`
LEFT JOIN (
SELECT `user_survey_status_entries`.`userSurveyID`,
MIN(timestamp) AS `timestamp`
FROM `user_survey_status_entries`
WHERE (status = 20)
GROUP BY `userSurveyID`
) AS `firstAccess` ON us.userSurveyID = firstAccess.userSurveyID
WHERE (us.surveyID = '10')
I can't figure out how to join the subquery using the doctrine 2.5 query builder. In the main query, I need to select columns from the subquery.
I have read here that doctrine does not support joining subqueries. If that's still true, can I write this query in another way using the SQL query builder of doctrine DBAL? Native SQL may not be a good solution for me, as this query will be dynamically extended later in the code.
I've found a solution by adapting this DQL example to DBAL. The trick is to get the raw SQL of the subquery, wrap it in brackets, and join it. Parameters used in the subquery must be set in the main query:
Important it's the createQueryBuilder of connection not the one of the entity manager.
$subSelect = $connection->createQueryBuilder()
->select(array('userSurveyID', 'MIN(timestamp) timestamp'))
->from('user_survey_status_entries')
// Instead of setting the parameter in the main query below, it could be quoted here:
// ->where('status = ' . $connection->quote(UserSurveyStatus::ACCESSED))
->where('status = :status')
->groupBy('userSurveyID');
$select = $connection->createQueryBuilder()
->select($selectColNames)
->from('user_surveys', 'us')
// Get raw subquery SQL and wrap in brackets.
->leftJoin('us', sprintf('(%s)', $subSelect->getSQL()), 'firstAccess', 'us.userSurveyID = firstAccess.userSurveyID')
// Parameter used in subquery must be set in main query.
->setParameter('status', UserSurveyStatus::ACCESSED)
->where('us.surveyID = :surveyID')->setParameter('surveyID', $surveyID);
To answer this part of your question:
I can't figure out how to join the subquery using the doctrine 2.5 query builder
You can make 2 query builder instances and use the DQL from the second one inside a clause of your first query. An example:
->where($qb->expr()->notIn('u.id', $qb2->getDQL())
Check examples here or here or find more using Google

Categories