How to write table alias in ActiveRecord in yii2 - yii2

I have a sql query like below -
SELECT
district, coalesce(sell.sale,0) as totalsale
FROM `districts`
left join
(SELECT parties_district, billdate, sum(billamount) as sale FROM `bills` left join parties on bills.bills_partyname = parties.parties_partyname group by parties_district) as sell
on sell.parties_district = districts.district
So far I've written the query till -
SELECT
parties_district, billdate, sum(billamount) as sale
FROM `bills`
left join parties
on bills.bills_partyname = parties.parties_partyname
group by parties_district
And my query in yii2 ActiveRecord looks like -
$query = Parties::find()
->select(['parties_district','parties_partyname','sum(billamount) as sale'])
->joinWith('bills')
->groupby('parties_district');
Please tell me how can I write the whole query. I think I'm stuck with the alias part and there is a subquery in it. Please tell me how can I write a subquery within a query.
I've tried -
$subQuery = Parties::find()->select(['parties_district','parties_partyname','sum(billamount) as sale'])->joinWith('bills sell')->groupby('parties_district');
$query = Districts::find()->select(['district','coalesce(sell.sale,0) as totalsale'])->leftJoin('$subQuery', 'sell.parties_district = districts.district');
$models = $query->all();
but getting the following error
Database Exception – yii\db\Exception
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'gm.$subquery' doesn't exist
The SQL being executed was: SELECT `district`, coalesce(sell.sale,0) as totalsale FROM `districts` LEFT JOIN `$subQuery` ON sell.parties_district = districts.district
Error Info: Array
(
[0] => 42S02
[1] => 1146
[2] => Table 'gm.$subquery' doesn't exist
)
↵
Caused by: PDOException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'gm.$subquery' doesn't exist

In this case is better use a literal notation for select content (and not hash notation) this way
$query = Parties::find()
->select('parties_district, parties_partyname, sum(billamount) as sale'])
->joinWith('bills')
->groupby('parties_district');
and for more complex query use findBySql Query
$sql = "SELECT
district, coalesce(sell.sale,0) as totalsale
FROM `districts`
left join
(SELECT parties_district, billdate, sum(billamount) as sale
FROM `bills` left join parties
on bills.bills_partyname = parties.parties_partyname
group by parties_district) as sell
on sell.parties_district = districts.district"
$model = Districts::findBySql($sql)->all();

I've figured out the answer. Thanks to this page - www.yiiframework.com/doc-2.0/guide-db-query-builder.html.
It will be like below -
$subQuery1 = (new Query())->select(['parties_district','billdate','sum(billamount) as sale'])->from ('bills')->join('LEFT JOIN','parties','bills.bills_partyname = parties.parties_partyname')->groupby('parties_district')->where('billdate != "NULL"');
$query = (new Query())->select(['district','coalesce(sell.sale,0) as totalsale'])->from('districts')->leftJoin(['sell' => $subQuery1],'sell.parties_district = districts.district');

Related

Cannot retrieve column using eloquent

I have a query that extracts student marks, but I want to also extract the name and surname of the student but I get the error
SQLSTATE[42000]: Syntax error or access violation: 1055 'shunifu_db.users.name' isn't in GROUP BY (SQL: select name, marks.student_id,ROUND(AVG(mark)) as mark from grades inner join grades_students on grades_students.grade_id = grades.id inner join users on grades_students.student_id = users.id inner join marks on marks.student_id = grades_students.student_id where grades.stream_id = 5 and assessement_id = 1 group by marks.student_id)
here is my code
$result = DB::table('grades')
->join('grades_students', 'grades_students.grade_id', '=', 'grades.id')
->join('users','grades_students.student_id','=','users.id')
->join('marks','marks.student_id','=','grades_students.student_id')
->where('grades.stream_id', $request->stream_name)
->where('assessement_id',$request->assessement)
->select(DB::raw('marks.student_id,ROUND(AVG(mark)) as mark'))
->groupBy('marks.student_id')
->get()
May be it will work
$result = DB::table('grades')
->join('grades_students', 'grades_students.grade_id', '=', 'grades.id')
->join('users','grades_students.student_id','=','users.id')
->join('marks','marks.student_id','=','grades_students.student_id')
->where('grades.stream_id', $request->stream_name)
->where('assessement_id',$request->assessement)
->select(DB::raw('users.id,users.name,ROUND(AVG(mark)) as mark'))
->groupBy(['users.id', 'users.name'])
->get()
Here I'm using user table for grouping and also fetching name.

MySQL: Invalid use of group function updating two columns with update/select

I am trying to update two columns within a table from a select statment in MySQL 5.7.
The error I get is "invalid use of group function"
Stmt:
UPDATE
catalog mpc
JOIN
reviews mpr ON mpr.merchant_id = mpc.MERCHANT_ID and mpr.sku = mpc.ARTICLE_ID
SET
mpc.RATING = avg(mpr.rating),
mpc.RATINGS = count(mpr.rating)
WHERE
mpr.MERCHANT_ID = 1
AND mpr.sku = '133';
It looks about right to me, what could be the problem here?
You must aggregate first in reviews and then join to catalog:
UPDATE catalog mpc
INNER JOIN (
SELECT merchant_id, sku, AVG(rating) avg_rating, COUNT(rating) count_rating
FROM reviews
WHERE merchant_id = 1 AND sku = '133'
GROUP BY merchant_id, sku
) mpr ON mpr.merchant_id = mpc.MERCHANT_ID and mpr.sku = mpc.ARTICLE_ID
SET mpc.RATING = mpr.avg_rating,
mpc.RATINGS = mpr.count_rating

Zf2 table gateway join query to fetch only the latest row(by id) from second table

Hi, I need a zf2 join query that fetches only the latest row(by id DESC) from the second table. I have written an sql query and it works.
SELECT st1.customer_id,
st1.id
FROM status st1
inner JOIN
(
SELECT max(id) MaxId, customer_id
FROM status
GROUP BY customer_id
) st2
ON st1.customer_id = st2.customer_id
AND st1.id = st2.MaxId
But I need this query at zend framework 2 table gateway format. Please help.
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Expression;
$sql = new Select ();
$sql->columns(["customer_id", new Expression ("max(id) AS MaxId")])
->from ('status')
->group('customer_id');
$outer = new Select ();
$outer->columns (['customer_id', 'id'])
->from (['st1' => 'status'])
->join (['st2' => $sql],
'st1.customer_id = st2.customer_id AND st1.id = st2.MaxId', []);

MYSQL query not returning proper set of rows

I have two tables:
table_subcategories - sub_categories_id, sub_category_name, sub_category_image_path
table_subcategory_categories - subcategory_id, category_id
I want to get all the subcategories from table_subcategories for which there is no mapping entry present in "table_subcategory_categories" with given category_id
I am using this query, but result is not correct.
my $sql_query = "SELECT TSC.sub_categories_id, TSC.sub_category_name, TSC.sub_category_image_path from table_subcategories as TSC
INNER JOIN
table_subcategory_categories as TSCC
ON
TSC.sub_categories_id = TSCC.subcategory_id
WHERE
TSCC.category_id != $cId ";
Can please some one help me to get what is wrong in this?
Use a left join and check for no matches:
SELECT TSC.*
from table_subcategories TSC LEFT JOIN
table_subcategory_categories TSCC
ON TSC.sub_categories_id = TSCC.subcategory_id AND
TSCC.Category_Id = $cId
WHERE TSCC.category_id IS NULL;

Rails 3, Kaminari - Error with :joins when using paginate

I have a function for prices with 2 joins and it works fine and dandy when I use it to call for prices. But now when I added Kaminari to be able to paginate, it gave me a error and I wonder if I can customize the "count*" function in Kaminari or is it my function for calling the products that's wrong?
This is in my controller
#prices = Price.select("`prices`.*").joins(:retailer, :retailer => :profile).
where(['product_id=? AND size_id=?', params[:prod_id], params[:si_id]]).
group(:retailer_id).order("SUM((prices.price * #{params[:amount].to_i}) + profiles.shippingCost)").page(params[:page])
Error code:
Mysql2::Error: Column 'retailer_id' in field list is ambiguous: SELECT COUNT(*) AS count_all, retailer_id AS retailer_id FROM `prices` INNER JOIN `retailers` ON `retailers`.`id` = `prices`.`retailer_id` INNER JOIN `profiles` ON `profiles`.`retailer_id` = `retailers`.`id` WHERE (product_id='1' AND size_id='3') GROUP BY retailer_id,retailer_id ORDER BY SUM((prices.price * 1) + profiles.shippingCost)
When I call the products without Kaminari the MYSQL looks like this.
SELECT `prices`.* FROM `prices` INNER JOIN `retailers` ON `retailers`.`id` = `prices`.`retailer_id` INNER JOIN `profiles` ON `profiles`.`retailer_id` = `retailers`.`id` WHERE (product_id='1' AND size_id='3') GROUP BY retailer_id ORDER BY SUM((prices.price * 1) + profiles.shippingCost)
Thanks in advance!
If ambiguous error then try explicit syntax for retailer_id.
e.g. retailers.retailer_id ,
profiles.retailer_id ,
prices.retailer_id.
ray
:retailer is duplicated inside your join clause.
Please change your join params to
.joins(:retailer => :profile)