How do I print out a long BIGINT in Yii in PHP? - php

When I print a BIGINT in Yii, it is rounding to MAX_INT. How do I print longs in Yii?
foreach ($negativeKeywords as $i=>$v) {
echo "$i: Removing $v->id, $v->campaign_id, $v->keyword, $v->google_id\n";
# 11: Removing 103, 2, gamtech, 2147483647
Real values:
=> select * from negative_keyword where id in (103,413);
id | campaign_id | keyword | match_type | status | google_id | bing_id
-----+-------------+------------+------------+--------+-------------+---------
103 | 2 | gamtech | 3 | 0 | 31883722149 |
=> \d negative_keyword;
Column | Type | Modifiers
...
google_id | bigint |
Here is the migration which created the table
$this->createTable('negative_keyword', [
'id' => Schema::TYPE_PK,
'google_id' => Schema::TYPE_BIGINT,
...
PHP 5.6.12 (cli) (built: Aug 11 2015 13:13:58)

Try this : You need to add max value of Bigint.
public function rules(){
return [
[['number_min'],'number','min'=>10],
[['number_max'],'number','max'=>100],
[['number_min_max'],'number','min'=>10,'max'=>100],
];
}

You can convert it to string while retrieving data through Query:
MYSQL
SELECT CONVERT(google_id, CHAR(10))
FROM negative_keyword;
Increase CHAR length accordingly...
For more info check this Reference
PostgreSQL
By Using to_char(), you can convert it into String in PostgreSQL
to_char(int, text)
For more info check this Reference

Sometimes you need to convert the BIGINT to a VARCHR in Postgres.
$accounts = Account::find()->select(['*', 'google_id' => 'cast(google_id as varchar)'])->all();
The 'number' rule by itself doesn't always work (esp. Postgres 9.4).

Related

Providing the Custom Name to both Key and Value Pairs of an Array

I have a table named questions in the following form:
Table Name: questions
qn_id | question |
---------------------------------------------------------------
19 | What is your rating on your Team Work?
20 | What is your rating on your Skills?
21 | What is your rating on your Personal Quality?
I have another table named rating as shown below:
Table Name: rating
id | employee_id | question_id | self_score | supervisor_score
-----------------------------------------------------------------
1 | 205 | 19 | 4 | 3
2 | 205 | 20 | 5 | 4
3 | 205 | 21 | 4 | 5
Note: There are two people involved in providing the score. One is supervisee and another is supervisor.
The score provided by the supervisee is kept in the column named self_score. In the table, employee_id is the id of the supervisee. Supervisor also gives the rating to the supervisee for the same question as shown aboove in the table.
I have generated the data from the database as an Array which is shown below:
$params = Array
(
[selfscore_19] => 4
[supervisorscore_19] => 3
[selfscore_20] => 5
[supervisorscore_20] => 4
[selfscore_21] => 4
[supervisorscore_21] => 5
)
Note: In the key named [selfscore_19] , selfscore_ is the string and 19 is the question id.
Questions are same for both - 'self' and 'supervisor'.
So I have appended the strings named 'selfscore' and 'supervisorscore' with the question_id.
In the array shown below, key is: [selfscore_19] which has been appended with the question_id i.e 19 and
the value is score provided by 'self' which is 4.
And other data follows similar pattern.
Attempt:
The code below shows the attempt done by me so far:
Note: I have only shown the main part of the method.
foreach($params as $key => $value){
$exp_key = explode('_', $key);
if($exp_key[0]=='selfscore'){
$arr_result[] = $value;
}
}
foreach($params as $key => $value){
$exp_key = explode('_', $key);
if($exp_key[0]=='supervisorscore'){
$arr_result[] = $value;
}
}
if(isset($arr_result)){
echo '<pre>';
print_r($arr_result);
echo '<pre>';
}
This is the output of the above code:
Current Output:
Array
(
[0] => 4
[1] => 5
[2] => 4
[3] => 3
[4] => 4
[5] => 5
)
Now I want to tranform the Current Output in the form of following Output.
Although I have already researched about this case, but I am finding it a bit tricky.
What modification should I do to achieve the required output?
Suggestions are highly appreciated.
Required Output:
$score['self_score']=array(
array('question_id'=>19,'score'=>4)
array('question_id'=>20,'score'=>5)
array('question_id'=>21,'score'=>4)
);
$score['supervisor_score']=array(
array('question_id'=>19,'score'=>3),
array('question_id'=>20,'score'=>4)
array('question_id'=>21,'score'=>5)
);
Do it with a single loop. Use the first part of $exp_key as the key of the resulting array, and the second part as the value of the question_id key of the sub-array.
foreach ($arr_result as $key => $value) {
$exp_key = explode("_", $key);
$score[$exp_key[0]][] = array("question_id" => $exp_key[1], "score" => $value);
}
I think I'll recommend that you use a UNION to join two simple queries so that your initial resultset is very close to what you want (close enough to simply iterate and/or modify it).
SQL: (Demo)
(SELECT 'group' AS 'self_score', question_id, self_score
FROM rating
WHERE employee_id = 205
ORDER BY id)
UNION
(SELECT 'supervisor_score', question_id, supervisor_score
FROM rating
WHERE employee_id = 205
ORDER BY id)
Resultset:
group | question_id | self_score
------------------|---------------|------------
self_score | 19 | 4
self_score | 20 | 4
self_score | 21 | 5
supervisor_score | 19 | 3
supervisor_score | 20 | 4
supervisor_score | 21 | 5
If you are open to a PDO solution, fetchAll(PDO::FETCH_GROUP) will come in pretty handy.

Parse through a nested array and save it in mysql db with parent id

I have a nested array like the following:-
array(
array(
'id' => 45cfeteuid536hjj929,
'name' = 'Cuisines',
'children' => array(
array(
'id' => 45gcfeteuid536hjj929,
'name' = 'Itlaian',
),
array(
'id' => 45bjfe78ng5d536hjj92,
'name' = 'Indian',
'children' => array(
array(
'id' => 457hfe78ng5d53ghy56j,
'name' = 'Punjabi'
)
)
)
)
)
);
I have a table like this:-
|--------------------------------|
| id | name | parent_id |
|--------------------------------|
I want data to be inserted like this:-
|---------------------------------------------------------------|
| id | name | parent_id | api_id |
|---------------------------------------------------------------|
| 1 | Cuisines | 0 | 45cfeteuid536hjj929 |
|---------------------------------------------------------------|
| 2 | Italian | 1 | 45gcfeteuid536hjj929 |
|---------------------------------------------------------------|
| 3 | Indian | 1 | 45bjfe78ng5d536hjj92 |
|---------------------------------------------------------------|
| 4 | Punjabi | 3 | 457hfe78ng5d53ghy56j |
|---------------------------------------------------------------|
The parent_id of the child is the id of the object to which it belongs. The id of the table are autoincrement value generated automatically by the mysql db.
For example:-
Step 1: While saving Cuisine, the id (autoincrement in nature) saved
is 1. Since it is the root, hence parent_id = 0.
Step 2: While saving Italian, the id (autoincrement in nature)
saved is 1. Since it is a child of Cuisines, the parent_id = 1
How can I save the nested array in such way?
One way would be to generate insert statements that look like this (assuming your table is called tab):
insert into tab(name, parent_id, app_id)
select 'Cuisines', coalesce(min(id), 0), '45cfeteuid536hjj929' from tab
where app_id = '';
insert into tab(name, parent_id, app_id)
select 'Itlaian', coalesce(min(id), 0), '45gcfeteuid536hjj929' from tab
where app_id = '45cfeteuid536hjj929';
insert into tab(name, parent_id, app_id)
select 'Indian', coalesce(min(id), 0), '45bjfe78ng5d536hjj92' from tab
where app_id = '45cfeteuid536hjj929';
insert into tab(name, parent_id, app_id)
select 'Punjabi', coalesce(min(id), 0), '457hfe78ng5d53ghy56j' from tab
where app_id = '45bjfe78ng5d536hjj92';
These queries will find the parent ID via the app_id that parent should have. No value for the id column is inserted, as it is assumed that the database will generate it upon insertion.
Here is a recursive PHP function which generates those statements. You'll have to adapt it to actually execute those statements with whatever API you use (PDO, mysqli, ...):
function insertRecords($data, $parent = "") {
foreach($data as $row) {
// Replace next echo statement with the code to actually execute this SQL:
echo "insert into tab(name, parent_id, app_id) select '$row[name]', coalesce(min(id), 0), '$row[id]' from tab where app_id = '$parent';\n";
if (isset($row["children"])) insertRecords($row["children"], $row["id"]);
}
}
Assuming your nested data structure is stored in variable $data, call the above function like this:
insertRecords($data);

Yii relation STAT with multiple columns

i'm trying to get a STAT relation from a Review table. This is my code
public function relations()
{
return array(
'avarageRating' => array(SELF::STAT, 'Reviews', array('make_code'=>'make_code', 'model_code'=>'model_code', 'year'=>'year'), 'select' => 'AVG(overall_rating)'),
}
the table would look something like this
make_code | model_code | year | overall_rating
01 | 02 | 2015 | 4.2
01 | 03 | 2014 | 4.0
01 | 02 | 2015 | 3.0
i want to get the overall_rating average for all rows that have the same make_code, model_code and year
example, make_code 01, model_code 02 and year 2015. (4.2+3.0 / 2), $model->avarageRating should give me 3.6
Right now, when i call the relation using $model->avarageRating; i get an error
preg_match() expects parameter 2 to be string, array given
any idea what i'm doing wrong?
EDITED:
function getavarageRating() {
$criteria = new CDbCriteria();
$criteria->select='ROUND(AVG(overall_rating), 1) AS avg, COUNT(overall_rating) AS total';
$criteria->addCondition("make_code=:make_code");
$criteria->addCondition("model_code=:model_code");
$criteria->addCondition("year=:year");
$criteria->params = array(':make_code' => $this->make_code, ':model_code' => $this->model_code, ':year' => $this->year);
$query = Reviews::model()->find($criteria);
return $query;
}
i added this function in my model, and this workws. but i there a way to use relations instead?
Seems you get a collection for your result so you should access by index , try accessing the first element as
$model[0]->avarageRating;

How many values of an array in a MySQL string

I have a simple array with some values:
$firstArray = array (
['val1'] => 'a',
['val2'] => 'b',
['val3'] => 'c'
);
and I would like to find how many values of this array appear in every line of a MySQL table like this one:
| ID | Name | Val |
| 01 | voice1 | a,c,d,e | // it should return 2 (a and c)
| 02 | voice2 | a,b,c,d,f | // it should return 3 (a,b and c)
The best thing should be to have an array with ID, name, and how many values.
You can use the FIND_IN_SET that will return you the position of the matched value and convert it to 1 or 0 with the SIGN function.
select
SIGN(FIND_IN_SET('a', texte)) +
SIGN(FIND_IN_SET('b', texte)) +
SIGN(FIND_IN_SET('c', texte))
from your_table;
This returns exactly what you expected with your test data-set.
Regards,

How do I combine two MySQL rows into one and display them in a table using PHP?

I have a table "exercise_results". People put in their results at the beginning and then two months later put in their results to see how much they improved. Their beginning set has the exercise_type_id of "1" and the end set has the exercise_type_id of "2".
I need a way to display this out into a HTML table that looks like this:
a foreach loop, but that's with single rows. I'm having trouble combining two rows into one. I think this may be as simple as some kind of MySQL join? We identify each person by their person_unique_id.
Here are my fields:
id | person_unique_id | person_name | exercise_type_id | mile_running_time | bench_press_weight_lbs | squat_weight_lbs | date_of_exercise_performed
Sample rows:
1 | J123 | John Smith | 1 | 8 | 200 | 300 | 2010-03-20
2 | J123 | John Smith | 2 | 7 | 250 | 400 | 2010-05-20
3 | X584 | Jane Doe | 1 | 10 | 100 | 200 | 2010-03-20
4 | X584 | Jane Doe | 2 | 8 | 150 | 220 | 2010-05-20
I've tried a few solutions but I'm lost. Any help would be great. Thanks!
EDIT:
In response to the comment below, I would hope for some data like:
array 0 =>
array
'Exercise' =>
array
'person_unique_id' => string 'J123'
'person_name' => string 'John Smith'
'begin_mile_running_time' => string '8'
'end_mile_running_time' => string '7'
1 =>
array
'Exercise' =>
array
'person_unique_id' => string 'X584'
'person_name' => string 'Jane Doe'
'begin_mile_running_time' => string '10'
'end_mile_running_time' => string '8'
You can use GROUP_CONCAT() to get a two rows result like this:
SELECT person_unique_id, person_name,
group_concat( mile_running_time ) AS miles,
group_concat( bench_press_weight_lbs ) AS bench,
GROUP_CONCAT( squat_weight_lbs ) AS squat
FROM exercise_result
GROUP BY person_unique_id
Your result will be like:
J123 | John Smith | 8,7 | 200,250 | 300,400
X584 | Jane Doe | 10,8 | 100,150 | 200,220
And then you can use php explode with the result fields to get the results for each type.
Extract the whole table, or whichever rows are interesting to you, sort on person id, compare person id of each row with the next to see if there is a result to print for all columns in your HTML table. If not, jump to the next and leave the fields blank(or some other solution, maybe ignore persons who have not filled in both fields?).
My PHP skills are limited, so no code example.
$query = mysql_query("select ...your data");
while ($row = mysql_fetch_assoc ($query) ) {
if ($row['exercise_type_id']==1)
$exe1[]=$row;
else
$exe2[]=$row;
}
print_r($exe1);
print_r($exe2);
from what I've understood
edit:
try this
$query = mysql_query("select ...your data");
while ($row = mysql_fetch_assoc ($query) ) {
$rows[]=array('Exercise'=>$row);
}
print_r($rows);
If you are ordering on person_unique_id then exercise_type_id, you can do this. If you have two rows for everyone, you can leave out the if (only use the else):
for( $i = 0; $i < count($exercise_results); $i++ )
{
$first = $exercise_results[$i];
if( !isset($exercise_results[$i+1])
|| $first['person_unique_id'] != $exercise_results[$i+1]['person_unique_id' ) {
$second = array(
'person_name'=>$other['person_name'],
'mile_running_time' => null // fill in the rest with defaults (like null)
);
} else {
$second = $exercise_results[$i+1];
$i++; // skip ahead one, since you've already used the second result.
}
// perform your normal printing, but use $beginning and $end to get the respective results
}

Categories