Laravel Query Builder - how to format the query using joins - php

I know this is a poorly written query. How can I re-write this using the Laravel Query builder?
SELECT tgi.rate, tgi.tax_types_id, tt.name, tt.sales_chart_master_id, tt.purchase_chart_master_id
FROM tax_group_items tgi, tax_types tt
WHERE tgi.tax_groups_id = (SELECT tax_groups_id FROM customers WHERE id=2)
AND tt.id = tgi.tax_types_id
AND tt.id NOT IN (SELECT tax_types_id FROM item_tax_type_exemptions WHERE item_tax_types_id = (SELECT item_tax_types_id FROM products WHERE id = 1))

The answer would be more easier and clearer to you if you post your relationships in the model class. If you dont know how to define relations, go to query builder section of official doc.
If you don't want to define relations or don't want to use them then use this
$query = DB::select('your query');

DB::table(DB::raw('tax_group_items tgi, tax_types tt'))
->select(['tgi.rate', 'tgi.tax_types_id', 'tt.name', 'tt.sales_chart_master_id', 'tt.purchase_chart_master_id'])
->whereRaw('tgi.tax_groups_id = (SELECT tax_groups_id FROM customers WHERE id=2)')
->where('tt.id', 'tgi.tax_types_id')
->whereRaw('tt.id NOT IN (SELECT tax_types_id FROM item_tax_type_exemptions WHERE item_tax_types_id = (SELECT item_tax_types_id FROM products WHERE id = 1))')
->get();

Related

sql query to laravel query with union

I want to convert the below union query to laravel query
DB::select("select lead_master.lead_stage from lead_master inner join user_master on
user_master.user_name=lead_master.assigned_user_name where region in (".$geo_string.") and teams
in (".$filter_teams_string.") group by (lead_stage) union
select meeting_hash from meetings_master where assigned_user_name in
(".$filter_username_string.") and meeting_hash in ('follow_up','first_time') group by
(meeting_hash)
union
select sales_stage from opportunity_master where sales_stage in ('Identified','QO_to be
approved') and assigned_user in (".$filter_username_string.") group by (sales_stage)");
below query woeking fine in postgre
Before this start, I assume that you understand about laravel Eloquent
Assume your lead_master table is LeadMaster Model , also the MeetingsMaster and OpportunityMaster
$lead_master = LeadMaster::select("lead_master.lead_stage as stage")
->join('user_master','user_master.user_name','=','lead_master.assigned_user_name')
->whereIn('region',$geo) //$geo is an array
->whereIn('teams',$filter_username) //also an array
->groupBy('lead_stage');
$meetings_master = MeetingsMaster::select('meeting_hash as stage')
->whereIn('assigned_user_name',$filter_username)
->whereIn('meeting_hash',['follow_up','first_time'])
->groupBy('meeting_hash');
$opportunity_master = OpportunityMaster::select('sales_stage as stage')
->whereIn('sales_stage',['Identified','QO_to be approved'])
->whereIn('assigned_user',filter_username)
->groupBy('sales_stage');
$query = $lead_master->union($meetings_master)->union($opportunity_master)->pluck('stage'); //your result
dd($query);
So thats how its look like when you using Laravel Eloquent
ps : You don't need to make 3 variables for that, I just use it to easy handle for maintenance

Yii2 translating findBySql query to QueryBuilder query

I have the following query using findbysql:
$query = Users::findBySql('select a.user_id, a.last_name,a.first_name, a.emp_id, ar.role_id from auth_users a, auth_user_roles AR, AUTH_USER_DEPTS AD, DEPARTMENTS D
where AD.DEPT_ID = D.DEPT_ID AND AR.USER_ID = AD.USER_ID and a.user_id = ar.user_id
AND D.DEPT_GROUP_ID = :dept_group_id AND (ACCESS_END_DATE > SYSDATE OR ACCESS_END_DATE IS NULL)
UNION
SELECT DISTINCT a.user_id, a.last_name, a.first_name, a.emp_id, NULL AS role_id FROM auth_users a, AUTH_USER_ROLES AR, AUTH_USER_DEPTS AD, DEPARTMENTS D
WHERE AD.DEPT_ID = D.DEPT_ID AND AR.USER_ID = AD.USER_ID and a.user_id = ar.user_id
AND D.DEPT_GROUP_ID = :dept_group_id AND
AR.ACCESS_END_DATE < SYSDATE AND AR.USER_ID NOT IN (select USER_ID from auth_user_roles where ACCESS_END_DATE > SYSDATE OR ACCESS_END_DATE IS NULL)', [':dept_group_id' => $dept_group_id ]);
This query does exactly what I want it to, but the problem is when I try to put it into a gridview it does not sort. According to Sort and search column when I'm querying with findbysql in yii2 it seems like I need to use query builder instead.
So I was trying to do that with the first part of my query (before the union), and it looks like so:
$query1 = (new \yii\db\Query())
->select(['user_id', 'last_name', 'first_name', 'emp_id'])
->from('AUTH_USERS');
$query2 = (new \yii\db\Query())
->select('USER_ID')
->from('AUTH_USER_ROLES')
->where('ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL');
$query = $query1->innerJoin('AUTH_USER_DEPTS', 'AUTH_USER_DEPTS.user_id = AUTH_USERS.user_id')->innerJoin('DEPARTMENTS', 'AUTH_USER_DEPTS.dept_id = DEPARTMENTS.dept_id');
$query->innerJoin('AUTH_USER_ROLES', 'AUTH_USER_ROLES.USER_ID = auth_users.USER_ID')->where('ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL');
However, my query comes out like this in yii and apparently oracle is not accepting the double quotes around the column names:
SELECT "user_id", "last_name", "first_name", "emp_id" FROM "AUTH_USERS"
INNER JOIN "AUTH_USER_DEPTS" ON AUTH_USER_DEPTS.user_id = AUTH_USERS.user_id
INNER JOIN "DEPARTMENTS" ON AUTH_USER_DEPTS.dept_id = DEPARTMENTS.dept_id
INNER JOIN "AUTH_USER_ROLES" ON AUTH_USER_ROLES.USER_ID = auth_users.USER_ID
WHERE ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL
I know the query might be incorrect here already but I cant even get the double quotes to go away. Tried defining the select statements multiple ways suggested by the yii docs already with no success:
select(['user_id', 'last_name', 'first_name', 'emp_id'])
select('user_id', 'last_name', 'first_name', 'emp_id')
select("user_id, last_name,first_name,emp_id")
I have also tried joining the queries like this from the docs: http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html
$query = $query1->innerJoin(['u' => $query2], 'u.user_id = user_id');
but it also complains that it doesnèt recognize u and the query instead comes out like so in yii:
SELECT COUNT(*) FROM "AUTH_USERS" INNER JOIN "AUTH_USER_DEPTS" ON AUTH_USER_DEPTS.user_id = AUTH_USERS.user_id INNER JOIN "DEPARTMENTS" ON AUTH_USER_DEPTS.dept_id = DEPARTMENTS.dept_id INNER JOIN (SELECT "USER_ID" FROM "AUTH_USER_ROLES" WHERE ACCESS_END_DATE>SYSDATE OR ACCESS_END_DATE IS NULL) "u" ON u.user_id = auth_users.user_id
At this point im just looking for the easiest way to build this query (whether it be using querybuilder or some other way) so that I can pass the query to my gridview and sort it.
I would recommend you first create all the data models you need from the tables you need for the query, using Gii it should be easy and it even creates the relationships you will need.
After that, you can do something like the following:
$query = Users::find()
->joinWith('theRelation1Name')
->joinWith('theRelation2Name')
->joinWith('theRelation3Name')
...
This way you don't need to give tables aliases or add the conditions needed for the relations to work.

Eloquent multiple select in the same query

Doing my firsts steps in eloquent, I'm trying to achieve a query that retrieve some data and count some conditions at the same time.
This raw SQL sentence works as expected
SELECT *
FROM photos,
(SELECT COUNT(*) FROM photos where type = 1 and published =1 group by type) as qA,
(SELECT COUNT(*) FROM photos where type = 2 and published =1 group by type) as qP
where product_id = 7
and published = 1
But using Photo model I can't get the same results
Photo::select(*,
Photo::raw('count(*) where type = 1 and published =1 group by type as qA),
Photo::raw('count(*) where type = 2 and published =1 group by type as qP))
->where ('product_id',7)
->where('published', 1)
->get()
Stripping out "raw" sentences, this query works, but I need to count those "type" ocurrences.
Thanks in advance for any guide over it.
Do you really need to get all in one query? Does it make sense for your application? I mean, I guess those types count are not really information about the record(s?) you are fetching (product_id = 7), rather they are general information about the state of the table as a whole.
If this makes sense, you could try
$photo = Photo::where ('product_id',7)
->where('published', 1)
->get();
$types_count = Photo::where('published', 1)
->selectRaw('type, COUNT(*) AS count')
->groupBy('type')
->get()
->keyBy('type');
$qA = $types_count[1]->count;
$qP = $types_count[2]->count;

How to optimize sub query in kohana

models.php
->add_subquery('(SELECT character_name FROM zid_character_details WHERE character_detail_id = (SELECT character_detail_id from zid_guild_feeds where feed_id = feeds.guild_parent_feed_id)) AS guildcharacter')
->add_subquery('(SELECT character_detail_id FROM zid_character_details WHERE character_detail_id = (SELECT character_detail_id from zid_guild_feeds where feed_id = feeds.guild_parent_feed_id)) AS guildcharacter_id')
->add_subquery('(SELECT character_icon FROM zid_character_details WHERE character_detail_id = (SELECT character_detail_id from zid_guild_feeds where feed_id = feeds.guild_parent_feed_id)) AS guildcharacter_icon')
Above is the three sub-query I am using to take the character_name, character_detail_id & character_icon from zid_character_details table with reference from zid_guild_feeds table.
Can anyone tell me how to optimize this three query into single or simple one.
Thanks
Have a look at Kohana Query Builder Joins and Kohana Query Builder Subqueries
When you need to explore various ORM's, I would advise that you have a look at Leap ORM

Cumulative DQL with Doctrine

Im having a hard time working out a proper DQL to generate cumulative sum. I can do it in plain SQL but when it comes to DQL i cant get hold of it.
Here is how it looks in SQL:
SELECT s.name, p.date_short, p.nettobuy,
(select sum(pp.nettobuy) as sum from price pp where pp.stock_id = p.stock_id and p.broker_id = pp.broker_id and pp.date_short <= p.date_short) as cumulative_sum
FROM price p
left join stock s on p.stock_id = s.id
group by p.stock_id, p.date_short
order by p.stock_id, p.date_short
Thanks
Hey, I have check the documentation for Doctrine 1.2, and the way to create the query is (put attention on the alias):
$query = Doctrine_Query::create();
$query->addSelect('AVG(price) as price');
$query->addSelect('AVG(cost) as cost');
// as many addSelect() as you need
$query->from('my_table');
To output the SQL query created:
echo $query->getSqlQuery();
To execute the statement:
$product = $query->fetchOne();
And to access the retrieved data is:
echo $product->getPrice();
echo $product->getCost();
Read the rest of the documentation at Group By Clauses.
You just specify the sum in your select part of the DQL:
$query = Doctrine_Query::create()
->select('sum(amount)')
->from('some_table');
Check out this page in the Doctrine documentation for more info.

Categories