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,
Related
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.
I have a table , similar to this:
| key | value |
|----------|-------|
| limit | 15 |
| viplimit | 25 |
| .. | |
And i have an array :
Array
(
[0] => Array
(
[key] => limit
[value] => 10
)
[1] => Array
(
[key] => viplimit
[value] => 99
)
...
Now , saying we have 100 rows. What would be the best way to update the table corresponding to the array ?
There would be the option of a query for each 100 row, but that is just bad performance.
This should work:
$statement = "UPDATE mytable
SET key = CASE id
WHEN 1 THEN 'key'
WHEN 2 THEN 'another_key'
WHEN 3 THEN 'some_key'
END,
value = CASE id
WHEN 1 THEN 15
WHEN 2 THEN 25
WHEN 3 THEN 45
END
WHERE id IN (1, 2, 3)
");
DB::statement($statement);
Just think how to create correct query. If it's admin panel or something that will be run not very often, I'd just use iteration to keep things simple.
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).
I have a array which always the number of its keys divided by 4 is integer (in oder words, mod is 0. for example in below example: [12 , 4] {div = 3 | mod = 0}).
My array is something like this:
$arr = Array
(
[0] => 'zero',
[1] => 'one',
[2] => 'two',
[3] => 'three',
[4] => 'four',
[5] => 'five',
[6] => 'six',
[7] => 'seven',
[8] => 'eight',
[9] => 'nine',
[10] => 'ten',
[11] => 'eleven'
);
Now I have a table with 4 column and I want to put all keys of my array into my table. In fact I want to insert each 4 keys of the array in 1 row of table. something like this:
// mytable
+---------+---------+---------+---------+
| col1 | col2 | col3 | col4 |
|---------------------------------------|
| zero | one | two | three |
| four | five | six | seven |
| eight | nine | ten | eleven |
+---------+---------+---------+---------+
I tried before asking and I concluded that I should use nested for(){}. Unfortunately, in reality my array has 1000 keys, and for this reason I can't do it manually. I know only the second for(){}:
for($i; I dont know the condition; $i++){
for ($j=0;$j<=3;$j++){ // selects 4 keys
$arr[$j];
}
INSERT INTO mytable VALUES ($arr[0],$arr[1],$arr[2],$arr[3]); // mysql codes
}
I know my codes are wrong, And please if you can help me. thanks
Actually you don't need a nested for. One is enough:
for ($j=0; $j<=count($array); $j+= ){ // selects 4 keys
INSERT INTO mytable VALUES ($arr[$j],$arr[$j+1],$arr[$j+2],$arr[$j+3]); // mysql codes
}
$j += 4; is the same as $j = $j + 4; it increases counter by 4.
Hope it helped :)
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
}