can anyone frame this sub query in yii2???
select name, crt_by, (select name from tbl_employee_master
where tbl_employee_master.contact = (select username from tbl_user
where tbl_user.id = tbl_dealer_master.crt_by)) as
employee, district, contact_person, contact,
(select count(*) from tbl_dealer_post
where tbl_dealer_post.fk_user_id = tbl_dealer_master.id)
as post_count from tbl_dealer_master
where status=1
Help is appreciable!!
Thanks in advance!!
Here is activequery you can use ..
$query= (new Query())->select([
'name' ,
'crt_by' ,
'employee' => (new Query())->select('name')
->from('tbl_employee_master')
->where([
'=','tbl_employee_master.contact', (new Query())
->select('username')
->from('tbl_user')
->where('tbl_user.id=tbl_dealer_master.crt_by')
]),
'district',
'contact_person',
'contact',
'post_count' => (new Query())->select('count(*)')
->from('tbl_dealer_post')
->where('tbl_dealer_post.fk_user_id=tbl_dealer_master.id')
])->from('tbl_dealer_master')->where(['status' => 1]);
This is the complete solution to the given problem!!
$query= (new Query())->select([
'name' ,
'crt_by' ,
'employee' => (new Query())->select('name')
->from('tbl_employee_master')
->where([
'=','tbl_employee_master.contact', (new Query())
->select('username')
->from('tbl_user')
->where('tbl_user.id=tbl_dealer_master.crt_by')
]),
'district',
'contact_person',
'contact',
'post_count' => (new Query())->select('count(*)')
->from('tbl_dealer_post')
->where('tbl_dealer_post.fk_user_id=tbl_dealer_master.id')
])->from('tbl_dealer_master')->where(['status' => 1]);
Related
I am trying to download data from database to excel file. I have import the Maatwebsite\Excel from composer also.
my code in my controller is:
function excel()
{
$month = date('m');
DB::statement("CREATE OR REPLACE VIEW monthly_cost AS
select user_name, id, phone, sum(cost) as cost from (
select users.name as user_name, users.roll as id,users.phone as phone, BC.individual_cost as cost
from breakfast_orders BO, breakfast_costs BC,users
WHERE (BO.date=BC.date) and (BO.user_id=users.id)and MONTH(BO.date)='$month'
UNION ALL
select users.name as user_name, users.roll as id,users.phone as phone, LC.individual_cost as cost
from lunch_orders LO, lunch_costs LC,users
WHERE (LO.date=LC.date) and (LO.user_id=users.id) and MONTH(LO.date)='$month'
UNION ALL
select users.name as user_name, users.roll as id,users.phone as phone, DC.individual_cost as cost
from dinner_orders ddO, dinner_costs DC,users
WHERE (ddO.date=DC.date) and (ddO.user_id=users.id) and MONTH(ddO.date)='$month'
) x group by id,user_name,phone");
$customer_data=DB::table('monthly_cost')->get()->toArray();
$customer_array[] = array('Name', 'ID', 'Phone', 'Cost', 'Month');
foreach($customer_data as $customer)
{
$customer_array[] = array(
'Name' => $customer->user_name,
'ID' => $customer->id,
'Phone' => $customer->phone,
'Cost' => $customer->cost,
'Month' => $month
);
}
Excel::create('Customer Data', function($excel) use ($customer_array){
$excel->setTitle('Customer Data');
$excel->sheet('Customer Data', function($sheet) use ($customer_array){
$sheet->fromArray($customer_array, null, 'A1', false, false);
});
})->download('xlsx');
}
what should I do now?
Just run php artisan config:clear or php artisan config:cache.
I am using Yii GridView filter and my data comes from Purcahses table.
That tables realted to
1 .vendors
2 .clients
Below are my relations in Purchases Model
'vendor' => array(self::BELONGS_TO, 'Vendors', 'Vendor'),
'client' => array(self::BELONGS_TO, 'Clientsinfo', 'clientID'),
and i am using that relations in my admin view , Below is code of admin.php file
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'purchases-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
array(
'name' => 'Vendor',
'value' =>'$data->vendor->VendorName',
),
array(
'name' => 'clientID',
'value' =>'$data->client->Company'
),
array(
'name' => 'PurchaseType',
'value' => 'Purchasetype::model()->findByPk($data->PurchaseType)->PurchaseType',
'filter' => '',
),
),
));
and lastly here is model search function where is use with and together to get data from other tables
public function search() {
$criteria = new CDbCriteria;
$criteria->together = true;
$criteria->with = array('vendor');
$criteria->with = array('client');
$criteria->compare('PurchaseType', $this->PurchaseType);
$criteria->compare('vendor.VendorName', $this->Vendor, true);
$criteria->compare('client.Company', $this->clientID, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
Getting data from client successufully , but when i use vendor fitter it throw me error below
CDbException
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column
'vendor.VendorName' in 'where clause'. The SQL statement executed was: SELECT COUNT(DISTINCT t.PurchaseID
) FROM purchases t LEFT OUTER JOIN clientsinfo client ON (t.clientID=client.ClInfoID
) WHERE ((Vendor=:ycp0) AND (vendor.VendorName LIKE :ycp1)) (C:\xampp\htdocs\laurenparker\framework
\db\CDbCommand.php:543)#0 C:\xampp\htdocs\laurenparker\framework\db\CDbCommand.php(433): CDbCommand-
queryInternal('fetchColumn', 0, Array)
Youre overriding relations in criteria. Change this:
$criteria->with = array('vendor');
$criteria->with = array('client');
To this:
$criteria->with = array('vendor', 'client');
Im new in laravel, and im trying to update my navigation tree.
So i want to update my whole tree in one query without foreach.
array(
array('id'=>1, 'name'=>'some navigation point', 'parent'='0'),
array('id'=>2, 'name'=>'some navigation point', 'parent'='1'),
array('id'=>3, 'name'=>'some navigation point', 'parent'='1')
);
I just want to ask - is there posibility in laravel to insert(if new in array) or update my current rows in database?
I want to update all, because i have fields _lft, _right, parent_id in my tree and im using some dragable js plugin to set my navigation structure - and now i want to save it.
I tried to use
Navigation::updateOrCreate(array(array('id' => '3'), array('id'=>'4')), array(array('name' => 'test11'), array('name' => 'test22')));
But it works just for single row, not multiple like i tried to do.
Maybe there is another way to do it?
It's now available in Laravel >= 8.x
The method's first argument consists of the values to insert or update, while the second argument lists the column(s) that uniquely identify records within the associated table. The method's third and final argument is an array of columns that should be updated if a matching record already exists in the database:
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
I wonder why this kind of feature is not yet available in Laravel core (till today). Check out this gist The result of the query string would look like this: here
I am putting the code here just in case the link breaks in the future, I am not the author:
/**
* Mass (bulk) insert or update on duplicate for Laravel 4/5
*
* insertOrUpdate([
* ['id'=>1,'value'=>10],
* ['id'=>2,'value'=>60]
* ]);
*
*
* #param array $rows
*/
function insertOrUpdate(array $rows){
$table = \DB::getTablePrefix().with(new self)->getTable();
$first = reset($rows);
$columns = implode( ',',
array_map( function( $value ) { return "$value"; } , array_keys($first) )
);
$values = implode( ',', array_map( function( $row ) {
return '('.implode( ',',
array_map( function( $value ) { return '"'.str_replace('"', '""', $value).'"'; } , $row )
).')';
} , $rows )
);
$updates = implode( ',',
array_map( function( $value ) { return "$value = VALUES($value)"; } , array_keys($first) )
);
$sql = "INSERT INTO {$table}({$columns}) VALUES {$values} ON DUPLICATE KEY UPDATE {$updates}";
return \DB::statement( $sql );
}
So you can safely have your arrays inserted or updated as:
insertOrUpdate(
array(
array('id'=>1, 'name'=>'some navigation point', 'parent'='0'),
array('id'=>2, 'name'=>'some navigation point', 'parent'='1'),
array('id'=>3, 'name'=>'some navigation point', 'parent'='1')
)
);
Just in case any trouble with the first line in the function you can simply add a table name as a second argument, then comment out the line i.e:
function insertOrUpdate(array $rows, $table){
.....
}
insertOrUpdate(myarrays,'MyTableName');
NB: Be careful though to sanitise your input! and remember the timestamp fields are not touched. you can do that by adding manually to each arrays in the main array.
I've created an UPSERT package for all databases: https://github.com/staudenmeir/laravel-upsert
DB::table('navigation')->upsert(
[
['id' => 1, 'name' => 'some navigation point', 'parent' => '0'],
['id' => 2, 'name' => 'some navigation point', 'parent' => '1'],
['id' => 3, 'name' => 'some navigation point', 'parent' => '1'],
],
'id'
);
Eloquent Style
public function meta(){ // in parent models.
return $this->hasMany('App\Models\DB_CHILD', 'fk_id','local_fk_id');
}
.
.
.
$parent= PARENT_DB::findOrFail($id);
$metaData= [];
foreach ($meta['meta'] as $metaKey => $metaValue) {
if ($parent->meta()->where([['meta_key', '=',$metaKey]] )->exists()) {
$parent->meta()->where([['meta_key', '=',$metaKey]])->update(['meta_value' => $metaValue]);
}else{
$metaData[] = [
'FK_ID'=>$fkId,
'meta_key'=>$metaKey,
'meta_value'=> $metaValue
];
}
}
$Member->meta()->insert($metaData);
No, you can't do this. You can insert() multiple rows at once and you can update() multiple rows using same where() condition, but if you want to use updateOrCreate(), you'll need to use foreach() loop.
I didn't find a way to bulk insert or update in one query. But I have managed with only 3 queries. I have one table name shipping_costs. Here I want to update the shipping cost against the shipping area. I have only 5 columns in this table id, area_id, cost, created_at, updated_at.
// first get ids from table
$exist_ids = DB::table('shipping_costs')->pluck('area_id')->toArray();
// get requested ids
$requested_ids = $request->get('area_ids');
// get updatable ids
$updatable_ids = array_values(array_intersect($exist_ids, $requested_ids));
// get insertable ids
$insertable_ids = array_values(array_diff($requested_ids, $exist_ids));
// prepare data for insert
$data = collect();
foreach ($insertable_ids as $id) {
$data->push([
'area_id' => $id,
'cost' => $request->get('cost'),
'created_at' => now(),
'updated_at' => now()
]);
}
DB::table('shipping_costs')->insert($data->toArray());
// prepare for update
DB::table('shipping_costs')
->whereIn('area_id', $updatable_ids)
->update([
'cost' => $request->get('cost'),
'updated_at' => now()
]);
in your controller
use DB;
public function arrDta(){
$up_or_create_data=array(
array('id'=>2, 'name'=>'test11'),
array('id'=>4, 'name'=>'test22')
);
var_dump($up_or_create_data);
echo "fjsdhg";
foreach ($up_or_create_data as $key => $value) {
echo "key ".$key;
echo "<br>";
echo " id: ".$up_or_create_data[$key]["id"];
echo "<br>";
echo " Name: ".$up_or_create_data[$key]["name"];
if (Navigation::where('id', '=',$up_or_create_data[$key]["id"])->exists()) {
DB::table('your_table_ name')->where('id',$up_or_create_data[$key]["id"])->update(['name' => $up_or_create_data[$key]["name"]]);
}else{
DB::insert('insert into your_table_name (id, name) values (?, ?)', [$up_or_create_data[$key]["id"], $up_or_create_data[$key]["name"]]);
}
}
I'm facing the error in title with Magento. I'm trying to group the records in the grid by county, which is one of the fields obtained in the join, not the main table. When I run the SQL query generated against DB it runs as expected but when trying to access the grid in Magento, I get that error. This is my join:
$collection = Mage::getModel('sales/order_address')->getCollection();
$collection
->addAttributeToSelect('region')
->addAttributeToSelect('city')
->addAttributeToFilter('address_type', 'shipping')
->addAttributeToFilter('region', 'California')
->addAttributeToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter(array('status', 'status'),
array(
array('eq' => 'complete'),
array('eq' => 'processing')
));
$collection->getSelect()->joinLeft(
array('order' => 'sales_flat_order'),
'order.entity_id = main_table.parent_id',
array('status' => 'order.status',
'created_at' => 'order.created_at',
'grand_total' => 'SUM(order.grand_total)'))
->joinLeft(
array('order_tax' => 'sales_order_tax'),
'order_tax.order_id = main_table.parent_id',
array('county' => 'order_tax.title',
'tax_amount' => 'SUM(order_tax.amount)',
'tax_rate' => 'order_tax.percent'))
->group('county')
->group('city')
->distinct(true);
And this is the generated SQL:
SELECT DISTINCT `main_table`.`region`, `main_table`.`city`, `order`.`status`, `order`.`created_at`, SUM(order.grand_total) AS `grand_total`, `order_tax`.`title` AS `county`, SUM(order_tax.amount) AS `tax_amount`, `order_tax`.`percent` AS `tax_rate` FROM `sales_flat_order_address` AS `main_table` LEFT JOIN `mvmt_sales_flat_order` AS `order` ON order.entity_id = main_table.parent_id LEFT JOIN `mvmt_sales_order_tax` AS `order_tax` ON order_tax.order_id = main_table.parent_id WHERE (address_type = 'shipping') AND (region = 'California') AND (created_at >= '2013-08-01 00:00:00' AND created_at <= '2013-12-31 00:00:00') AND ((status = 'complete') OR (status = 'processing')) GROUP BY `county`, `city`
Does someone knows what is happening here and why SQL is accepting the query but not Magento?
Thanks for the help in advance.
$collection = Mage::getModel('sales/order_address')->getCollection();
$collection
->addAttributeToSelect('region')
->addAttributeToSelect('country_id')
->addAttributeToSelect('city')
->addAttributeToFilter('address_type', 'shipping')
->addAttributeToFilter('region', 'California')
->addAttributeToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter(array('status', 'status'),
array(
array('eq' => 'Pending'),
array('eq' => 'processing')
));
$collection->getSelect()->joinLeft(
array('order' => 'sales_flat_order'),
'order.entity_id = main_table.parent_id',
array('order.status','order.created_at','SUM(order.grand_total)'));
$collection->getSelect()
->joinLeft(
array('order_tax' => 'sales_order_tax'),
'order_tax.order_id = main_table.parent_id',
array('order_tax.title','SUM(order_tax.amount)','order_tax.percent'))
->group('country_id')
->group('city')
->distinct(true);
Hope this will work for you. :)
Best of luck.
I have a calculated column I wanna have sortable.
I have a get method for it...
public function getCur_margin() {
return number_format(($this->store_cost / $this->store_price) / $this->store_cost * 100, 2) . '%';
}
And I followed this thread...
CGridview custom field sortable
But now it's looking for an actual column in the database. How can I fetch a field using <calculations> AS cur_margin only temporarily for this CActiveDataProvider?
Here is the controller code for the provider:
$dataProvider = new CActiveDataProvider('Products', array(
'criteria' => array(
'condition' => 'store_id IN (SELECT `id` FROM `stores` WHERE `user_id` = ' . Yii::app()->user->id . ')',
),
'pagination' => array(
'pageSize' => 15,
),
'sort'=>array(
'attributes'=>array(
'cur_margin' => array(
'asc' => 'cur_margin ASC',
'desc' => 'cur_margin DESC',
),
),
),
));
Have you tried to specify your custom field in select property of CDbCriteria?
'select' => array(
..., // fields to select
'(<calculations>) AS cur_margin'
)
You don't have to declare getCur_margin() method then but only declare a public $cur_margin member in your model. All required calculations will be done in SQL query.
You can also refer to this thread as an example.