ON DUPLICATE KEY UPDATE Query in Laravel4 - mysql

How do I transform this
DB::table('partners')->insert(array($data));
laravel Query to have ON DUPLICATE KEY UPDATE
the structure look like
$data['program_name'] = $program['program']['_'];
$data['program_id'] = $program_id;
$data['status'] = $program['status'];
$data['shop_name'] = $shop->name;
$data['shop_logo'] = $shop->image;
$data['shop_description'] = $shop->description;
where program_id is unique

Use something like this (feel free to correct because it's untested):
DB::statement( 'INSERT INTO partners VALUES (' . implode( ',',
array_map( function( $val ) { return ":$val"; } , array_keys($data) )
) . ') ON DUPLICATE KEY UPDATE ' . implode( ',',
array_map( function( $val ) { return "$val = VALUES($val)"; } , array_keys($data) )
), $data);

I created a package that will wrapped INSERT ON DUPLICATE KEY UPDATE
https://packagist.org/packages/yadakhov/insert-on-duplicate-key
$users = [
['id' => 1, 'email' => 'user1#email.com', 'name' => 'User One'],
['id' => 2, 'email' => 'user2#email.com', 'name' => 'User Two'],
['id' => 3, 'email' => 'user3#email.com', 'name' => 'User Three'],
];
User::insertOnDuplicateKey($users);
// produces:
INSERT INTO `test_user_table`(`id`,`email`,`name`) VALUES
(1,'user1#email.com','User One'), (2,'user3#email.com','User Two'), (3,'user3email.com','User Three')
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `email` = VALUES(`email`), `name` = VALUES(`name`)

Related

How to get sum value of usermeta key using another meta key

I have two meta key: us_points & agent_id
I need to sum up all the us_points value with agent ID same for each users.
Here is what I tried:
$cuser = wp_get_current_user(); $a_id = $cuser->agent_id;
global $wpdb;
$result = $wpdb->get_col("SELECT sum(meta_value) FROM $wpdb->usermeta WHERE meta_key = 'us_points' AND agent_id = $a_id" );
echo $result[0];
If I remove AND agent_id = $a_id, it shows the sum of all users in the website, but I need to show the sum of only the meta key value common/matching in agent_id
Help will me much appreciated.
Try this, It should target agent_id meta key then group records by the same agent_id value before summing.
$result = $wpdb->get_col("SELECT sum(meta_value) FROM $wpdb->usermeta WHERE meta_key = 'us_points' GROUP BY meta_value HAVING 'meta_key' = 'agent_id'" );
$users = get_users();
$agent_points = array();
foreach( $users as $user ) {
$agent_points[] = array(
'agent_id' => $user->agent_id,
'us_points' => $user->us_points,
);
}
$agent_points expected to be in the structure:
Array
(
[0] => Array
(
[agent_id] => 1
[us_points] => 30
)
[1] => Array
(
[agent_id] => 4
[us_points] => 10
)
[2] => Array
(
[agent_id] => 4
[us_points] => 30
)
[3] => Array
(
[agent_id] => 1
[us_points] => 20
)
)
Then,
$results= array();
foreach( $agent_points as $values ) {
foreach( $values as $key => $value ) {
if( 'agent_id' === $key ) {
$results[ $value ] += $values['us_points'];
}
}
}
Expected $results in agent_id => us_points pair:
Array
(
[1] => 50
[4] => 40
)

Missing required parameter in yii2 Search

i want to search the stock till a particular date. User will fill this date form. The first page where user go to input the date field is _formtilldate.
Controller action -
public function actionIndex3() {
//$enddate = '2018-03-01';
$searchModel1 = new SellitemSearch();
$dataProvider1 = $searchModel1->search ( Yii::$app->request->queryParams );
//$searchModel2 = new PuritemtilldateSearch();
//$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render ( '_formtilldate' , [
'model1' => $searchModel1 ,
//'enddate' => $enddate,
//'model2' => $searchModel2,
//'searchModel1' => $searchModel2,
] );
}
And the form field
<?php
$form = ActiveForm::begin ( [
'id' => 'form-id' ,
'action' => [ '/stock/sellitem/stocktilldate' , 'enddate' => $model1->enddate ] ,
'method' => 'get' ,
'enableClientScript' => false ,
] );
?>
<?=
$form->field ( $model1 , 'enddate' )->widget (
DatePicker::className () , [
// inline too, not bad
'options' => [ 'placeholder' => 'End Date ...' , 'id' => 'enddate1' ] ,
'inline' => false ,
//'id' => 'startdate1',
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true ,
'todayHighlight' => true ,
'format' => 'yyyy-mm-dd'
]
] );
?>
On clicking on the submit button, the search query runs -
Controller Action -
public function actionStocktilldate( $enddate ) {
//$enddate = '2018-03-01';
$searchModel1 = new SellitemtilldateSearch();
$dataProvider1 = $searchModel1->search ( Yii::$app->request->queryParams );
//$searchModel2 = new PuritemtilldateSearch();
//$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render ( 'indexstocktilldate' , [
//'enddate' => $enddate,
'searchModel1' => $searchModel1 ,
'dataProvider1' => $dataProvider1 ,
//'searchModel2' => $searchModel2,
//'dataProvider2' => $dataProvider2,
] );
}
Search Model -
public function search( $params , $enddate ) {
//$query = Sellitem::find();
$subQuery1 = (new Query() )->select ( [ 'pi_upc' , 'sum(pi_qty) as purchased' ] )->from ( 'puritem' )->leftJoin ( 'pursum' , 'pursum.ps_id = puritem.psi_id' )->andwhere ( [ '<' , 'pursum.ps_date' , $enddate ] )->groupby ( 'pi_upc' );
$subQuery2 = (new Query() )->select ( [ 'si_iupc' , 'sum(si_qty) as sold' ] )->from ( 'sellitem' )->leftJoin ( 'sellsum' , 'sellsum.ss_id = sellitem.si_ssid' )->andwhere ( [ '<' , 'sellsum.ss_date' , $enddate ] )->groupby ( 'si_iupc' );
$subQuery3 = (new Query() )->select ( [ 'i_upc' , 'i_category' , 'i_brand' , 'i_desc' , 'i_unit' , 'i_buyprice' , 'coalesce(p.purchased,0) as purchased' ] )->from ( 'item' )->leftJoin ( [ 'p' => $subQuery1 ] , 'p.pi_upc = i_upc' );
$query = (new Query() )->select ( [ 'tp.i_upc as upc' , 'tp.i_category as category' , 'tp.i_brand as brand' , 'tp.i_desc as description' , 'tp.i_unit as unit' , 'tp.purchased as purchased' , 'coalesce(ts.sold,0) as sold' , '(coalesce(purchased,0) - coalesce(sold,0)) as stock' , 'tp.i_buyprice as rate' , 'round(((coalesce(purchased,0) - coalesce(sold,0))*tp.i_buyprice),2) as value' ] )->from ( [ 'tp' => $subQuery3 ] )->leftJoin ( [ 'ts' => $subQuery2 ] , 'ts.si_iupc = tp.i_upc' );
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query ,
'pagination' => [
'pageSize' => 10000000000 ,
] ,
]);
......
}
Now, in the url I can see the parameter got passed -
http://localhost/chayanika/frontend/web/index.php?r=stock%2Fsellitem%2Fstocktilldate&SellitemSearch%5Benddate%5D=2018-08-13
But, I'm getting error -
Bad Request (#400)
Missing required parameter: enddate
I'm not getting where I'm missing it.
I made a bit progress here -
I just learned that the date I'm getting in the URL is coming from the Action in the form. But it's not of much use so far.
If I change the controller action a bit, I get a result -
public function actionStocktilldate() {
$enddate = date ( 'Y-m-d' );
//$enddate = yii::$app->request->get('enddate');
//var_dump($enddate);
$searchModel1 = new SellitemtilldateSearch();
$dataProvider1 = $searchModel1->search ( Yii::$app->request->queryParams , $enddate );
//$searchModel2 = new PuritemtilldateSearch();
//$dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);
return $this->render ( 'indexstocktilldate' , [
//'enddate' => $enddate,
'searchModel1' => $searchModel1 ,
'dataProvider1' => $dataProvider1 ,
//'searchModel2' => $searchModel2,
//'dataProvider2' => $dataProvider2,
] );
}
Please tell me how can I pass the date collected by the form to this controller.
In your url, I don't see enddate param, I just see:
frontend/web/index.php?r=stock/sellitem/stocktilldate&SellitemSearch[enddate]=2018-08-13"
It is SellitemSearch[enddate], not enddate
You should modify your url to
frontend/web/index.php?r=stock/sellitem/stocktilldate&enddate=2018-08-13"
or remove $enddate param from actionStocktilldate function.
How is action parameter treated in ActiveForm.
Query parameters in the action are ignored for GET method. We use
hidden fields to add them back Hidden inputs are created and they are
submitted so your form action goes to the right place.
So if you look into the form source from your browser there is a hidden input created with the name enddate which will be submitted automatically.
<form id="w0" action="http://localhost/chayanika/frontend/web/index.php?r=/stock/sellitem/stocktilldate" method="get">
<input type="hidden" name="enddate" value="2018-03-01"><button type="submit">Submit</button>
</form>
Reason
But in your case, it isn't submitting because there isn't any hidden field being created. Why? because the assignment of your $model->enddate is returning null. Make sure there is a valid timestamp or date string saved.
Track
Go to line 395 of \yii\web\UrlManager function createUrl($params).
If you are using enablePrettyUrl=>true then it will enter the first check and in the foreach it appends the query string params as key where value!==null.
if($this->enablePrettyUrl){
$cacheKey = $route . '?';
foreach($params as $key => $value){
if($value !== null){
$cacheKey .= $key . '&';
}
}
if you are using enablePrettyUrl=>false then it will skip to the last section
$url = "$baseUrl?{$this->routeParam}=" . urlencode($route);
if(!empty($params) && ($query = http_build_query($params)) !== ''){
$url .= '&' . $query;
}
return $url . $anchor;
and there it will fail the check if(!empty($params) && ($query = http_build_query($params)) !== ''){ as http_build_query($params) returns empty string for an array having a key with null value.
So make sure you have a date save and the current model does not have the date saved in database as null

wordpress wpdb update difficulties

Suppose I have a table in my wp database fruits:
CREATE TABLE `fruits` (
`fruit` varchar(99),
`istasty` tinyint(1)
)
INSERT INTO `fruits` (`fruit`, `istasty`) VALUES
('pear', 1),
('peach', 1),
('rotten strawberry', 1),
('strawberry', 1),
('banana', 1),
('apple', 1);
the goal is to update istasty to 0 in the 'rotten strawberry' row.
the class reference for wpdb in the wordpress codex gives:
$wpdb->update( $table, $data, $where, $format = null, $where_format = null );
so I've attempted the following:
$wpdb->update(
'fruits',
array(
'fruit' => 'rotten strawberry',
'istasty' => '0'
),
array( 'fruit' => 'rotten strawberry' ),
array(
'%s', // value1
'%d' // value2
),
array( '%d' )
);
Apparently this updates EVERY record to 'rotten strawberry', '1'.
What am I doing wrong here?
Try changing up that last array from array( '%d' ) into array( '%s' ). You are now telling the script that the where variable is an integer, which it is not.
Also you could remove 'fruit' => 'rotten strawberry' from your first array. In this array you place whatever you want to update. And all you want to do is set istasty to 0.

Selecting column alias filled with NULLs with Zend_Db

Is there any way you can select NULL as a column with Zend_db.
To make it clear, you could write a query:
SELECT id, name, age, NULL as ssn from dummy_table;
The result would have 4 columns id, name, age and ssn(filled with null). Is there any way to do this in Zend_Db. My guess was:
$columns = [
'id' => 'id',
'name' => 'name',
'age' => 'age',
NULL => 'ssn'
];
$select = $this->_db->select();
$select
->from('dummy_table', $columns)
But that won't work it will generate:
SELECT `dummy_table`.`id` AS `id`, `dummy_table`.`name` AS `name`, `dummy_table`.`age` AS `age`, `dummy_table`.`ssn` AS `` FROM `dummy_table`;
This query will fail. Is there any way you could do this using only Zend_Db ($this->_db->query('') is not an option)?
Have you tried using new Zend_Db_Expr('NULL') ?
You could do :
$null = new Zend_Db_Expr('NULL');
$columns = [
'id' => 'id',
'name' => 'name',
'age' => 'age',
$null => 'ssn'
];
$select = $this->_db->select();
$select
->from('dummy_table', $columns);

add values with 'on duplicate key'

I have the folowing array called $words
Array
(
[0] => Array
(
[token] => dwA
[pos] => *DII.7,8*
)
[1] => Array
(
[token] => nTr
[pos] => *DI.5,9*
)
[2] => Array
(
[token] => dwA
[pos] => *DI.2,8*
)
[3] => Array
(
[token] => nTr
[pos] => *DI.2,8*
))
I want to insert it with the following :
foreach ($words as $value)
{
$word = $value['token'];
$attestation = $value['pos'];
$insert="INSERT INTO Examples (Word, Attestation) VALUES ('$word', '$attestation')
mysql_query($insert) OR die(mysql_error());
}
The table 'Examples' has a key called ID with auto increasement;
the field word is 'unique'
what I want is that in the field 'Attestation' the values are added each time the 'word' is the same
so the result should be the following:
Id word Attestation
1 dwA *DII.7,8*, *DI.2,8*
2 nTr *DI.5,9*, *DI.2,8*
so I tried to add a 'on duplicate key' phrase
foreach ($words as $value)
{
$word = $value['token'];
$attestation = $value['pos'];
$insert="INSERT INTO Words2 (Word, Attestation) VALUES ('$word', '$attestation')
on duplicate key update Attestation =
";
mysql_query($insert) OR die(mysql_error());
}
but I can't figure out what I have to add after Attestation = so that the differents attestations are added one after the other, like for example : DI.5,9, DI.2,8
Or is the 'on duplicate key' not the correct way to do this?
Try this;
INSERT INTO Words2 (Word, Attestation) VALUES ('$word', '$attestation')
on duplicate key update Attestation = CONCAT(Attestation, ', ', '$attestation')
Although, it may a bit difficult to break those values apart later on. You may want to consider another table, so you can set up a one-to-many relationship.