Group Array items in PHP - php

I have the above array:
| Student First Name |Student Last Name | Age |Disability|
| Student_First_Name_1 |Student_Last_Name_1 | 30 | 1 |
| Student_First_Name_2 |Student_Last_Name_2 | 28 | 0 |
| Student_First_Name_3 |Student_Last_Name_3 | 21 | 0 |
| Student_First_Name_4 |Student_Last_Name_4 | 20 | 1 |
| Student_First_Name_5 |Student_Last_Name_5 | 22 | 0 |
and I want to grouped the students by age and Disability.
So if my code runs correctly I'll have the above results:
Student_First_Name_1 : Student_First_Name_4
Student_First_Name_3 : Student_First_Name_5
Student_First_Name_2
But instead I have the above:
Student_First_Name_1 : Student_First_Name_4
Student_First_Name_3 : Student_First_Name_5
Student_First_Name_2 : Student_Last_Name_3
Student_First_Name_2 : Student_Last_Name_5
My code is:
$StudentsForSID = $conn->prepare("SELECT * FROM members WHERE sid = :sid AND level = :level");
$StudentsForSID->execute([ 'sid' => $SelectedSID, 'level' => 'LRN_B1' ]);
while($row = $StudentsForSID->fetch(PDO::FETCH_ASSOC)){
$TempSelected[] = $row;
}
$count=count($TempSelected);
for($i=0; $i<$count-1; $i++){
for ($j = $i+1; $j < $count; $j++) {
if($TempSelected[$i]['disability']==$TempSelected[$j]['disability']){
if( abs($TempSelected[$i]['age']-$TempSelected[$j]['age']) <= 23 ){
$Student1 = $TempSelected[$j]['first_name'];
$Student2 = $TempSelected[$i]['first_name'];
print_r($Student1.'-'.$Student2.'<br/>');
}
}
}
}
I don't think I explained very well. So i edit the question.
What I want:
I want to make groups of 2 students with the same value in disability and the age difference between the 2 students to be equal or under 23.
So I have the above array with 5 students. From this array I'll make 3 groups and the groups will be the above (2 groups with 2 students with fulfilled the criteria, and 1 group with one student).
Can you help me?
Thank you

Why don't you use a double group by in your query?
Group by Age , Disability
This will actually group your results into two groups like you wanted so you will save the php sorting and those multiple if and for.

Related

PHP Compare items in an array

I have an array in PHP.
My array is the above:
| Student First Name |Student Last Name | Age |Disability|
| Student_First_Name_1 |Student_Last_Name_1 | 30 | 1 |
| Student_First_Name_2 |Student_Last_Name_2 | 28 | 0 |
| Student_First_Name_3 |Student_Last_Name_3 | 21 | 0 |
| Student_First_Name_4 |Student_Last_Name_4 | 20 | 1 |
and I want from this array to compare the entries and make groups and save them to database.
So the student_1 with entry 1 will be grouped with the Student_4 with entry 1 and the Student_2 with the Student_3.
My code is the above:
$count=count($TempSelected);
for($i=1,$j=0;$i<$count;$i++){
if($TempSelected[$j]['disability']==$TempSelected[$i]['disability']){
if( abs($TempSelected[$j]['age']-$TempSelected[$i]['age']) <= 23 ){
$Student1 = $TempSelected[$j]['first_name'].' '.$TempSelected[$j]['last_name'];
$Student2 = $TempSelected[$i]['first_name'].' '.$TempSelected[$i]['last_name'];
unset($TempSelected[$i]);
unset($TempSelected[$j]);
$FirstEntry = $conn->prepare("SELECT id FROM ".$TableName." WHERE Checked = 0 LIMIT 1");
$FirstEntry->execute();
$id = $FirstEntry->fetchColumn();
$data = [
'student_1' => $Student1,
'student_2' => $Student2,
'Checked' => 1,
'id' => $id,
];
$AddStudent = $conn->prepare("UPDATE ".$TableName." SET student_1=:student_1, student_2=:student_2, Checked=:Checked WHERE id=:id");
$AddStudent->execute($data);
}
}
$count=count($TempSelected);
}
But it only make a group and stops.
I want to stops when it make all the groups not only 1.
Can you help me?
I edit my array above and I entered exactly what I have in the array
You need to use nested loops to compare all the pairs of elements. Your code increments $i, but $j is always 0, so you're only comparing with the first student.
for ($i = 0; $i < $count-1; $i++) {
for ($j = $i+1; $j < $count; $j++) {
...
}
}

How to query based on multiple relations between columns - MySQL?

I have four columns in a properties table: property_id, value, id, material_id.
I also have an array of properties: Array $properties
The schema is a bit complicated, because I want to find the material_id based on the matching properties.
An example:
$properties = array(['property_id'=>1,'value'=>3],['property_id'=>2,'value'=>6],['property_id'=>3,'value'=>4]);
Example table output:
+----+-------------+-------------+-------+
| id | material_id | property_id | value |
+----+-------------+-------------+-------+
| 1 | 1 | 3 | 5 |
| 2 | 1 | 3 | 5 |
| 3 | 1 | 3 | 5 |
| 4 | 2 | 1 | 3 |
| 5 | 2 | 2 | 6 |
| 6 | 2 | 3 | 4 |
| 10 | 4 | 1 | 9 |
| 11 | 4 | 2 | 3 |
| 12 | 4 | 3 | 6 |
+----+-------------+-------------+-------+
Now, I need material_id that satisfies all the properties. How can I do that..? Do I need to use exist statement of MySQL?
Now, for each element in your array you will want to run a statement that looks like this:
SELECT material_id FROM properties WHERE property_id = 2 AND value = 3;
Do you need help on the php code also? You could run a for each loop, but I will need to know what way you are using to communicate with your database for more specifics.
edit
foreach ($properties as $foo => $bar)
{
$sql = 'SELECT material_id FROM properties WHERE ';
foreach ($bar as $key => $value)
{
$sql .= $key .' = '. $value .' AND ';
}
$sql .= 'true';
*run your PDO code on $sql here*
}
On behalf of performance, it's not a good idea to run a query per array's value. If you have an oversized array things can get pretty slower.
So, best solution can be to build a single query including all conditions presented on $properties array:
<?php
$properties = array(['property_id'=>1,'value'=>3],['property_id'=>2,'value'=>6],['property_id'=>3,'value'=>4]);
$qCondition = [];
foreach($properties as $prop) {
$q = sprintf("(property_id = %d AND value = %d)", $prop["property_id"], $prop["value"]);
$qCondition[] = $q;
}
// assuming that your database table name is 'materials'
$sql = sprintf("SELECT * FROM materials WHERE (" . implode(" OR ", $qCondition) . ")");
echo $sql;
Result:
SELECT * FROM materials
WHERE ((property_id = 1 AND value = 3) OR (property_id = 2 AND value = 6) OR (property_id = 3 AND value = 4))
Therefore, you need to run only one single query to get all desired rows.
You can play with suggested solution here: http://ideone.com/kaE4sw

Merge first column that has the same second column

I have an INNER JOIN query that returns this result:
first column | second column
2 | 15
5 | 16
6 | 16
5 | 18
6 | 22
I want to output them in my page like this:
first column | second column
2 | 15
5,6 | 16
| 18
| 22
Total first column: 2
It will combine the first column that has the same second column. And value of the combined first column will be share between them.
And would also tell the total first column (which in the example is 2).
I'm still trying with this code:
if($stmt = $con->prepare("SELECT firsttb.firstcolumn, secondtb.secondcolumn FROM firsttb INNER JOIN secondtb ON firsttb.connectid = secondtb.connectid WHERE firsttb.getid = ? ORDER BY secondtb.secondcolumn")){
$stmt->bind_param("i",$_GET["getid"]);
$stmt->execute();
$stmt->bind_result($firstcolumn,$secondcolumn);
$lastid = 0;
$total = 0;
$combine = "";
while($stmt->fetch()){
if($lastid == $secondcolumn){
$combine = $combine."".$firstcolumn;
$lastid = $secondcolumn;
}
else {
$totalrow = $totalrow + 1;
$lastid = $secondcolumn;
$combine = $secondcolumn;
echo $combine." | ".$secondcolumn."<br>";
}
}
$stmt->close();
echo "Total first column: ".$totalrow;
}
But only get this output:
first column | second column
2 | 15
5 | 16
5 | 18
6 | 22
Total first column: 4
It is okay to scrap my code and create it with your own. Just want to look for the right idea.

update table from array with different values where empty field

I have problem with my code, problem is data not update still NULL.
table A
year | period | code | user_id
2013 | 4 | 1231 |
2013 | 4 | 1232 |
2013 | 4 | 1233 |
2013 | 4 | 1234 |
2013 | 4 | 1235 |
Table B
user_id | user_name | cash
A1 | AB | 10
A2 | BC | 5
A3 | CD | 7
I will put table B user_id to table A user_id when cash >= 7
Table Result
year | period | code | user_id
2013 | 4 | 1231 | 10
2013 | 4 | 1232 | 7
2013 | 4 | 1233 |
2013 | 4 | 1234 |
2013 | 4 | 1235 |
here my code,
$arr = array();
$query = mysql_query("select user_id from tableB where cash >= 7");
while ($arrs = mysql_fetch_array($query)) {
$arr[] = $arrs[0];
}
$count = count($arr);
for ($i = 0; $i < $count; $i++) {
$sql = mysql_query("UPDATE tableA SET user_id ='$arr[$i]' WHERE year = 2013 and period = 4 and user_id IS NULL");
}
if ($sql) {
echo "success";
}
The operator in the query should be >= and not =>
check on this:
$arr[] = $arrs[0];
this now holds the first record of the result set. Expected that there is only one record with cash >= 7, that might be ok, but thats a risky assumption.
for ($i = 0; $i < $count; $i++) {
$sql = mysql_query("UPDATE tableA SET user_id ='$arr[$i]' WHERE year = 2013 and
period = 4 and user_id IS NULL");
}
in here $arr[$i] iterates over the fields of the first record, giving you in a sequence the values 'A3', 'CD' and 7 and you are running three useless updates on your table. Afterwards the column user_id in Table A has the value 7 and not 'A3' since this is the last value in your loop.
I have solution for my code,
$arr = array();
$query = mysql_query("select user_id from tableB where cash >= 7");
while ($arrs = mysql_fetch_array($query)) {
$arr[] = $arrs[0];
}
$q = mysql_query("select code from tableA order by code");
$index = 0;
while($codes = mysql_fetch_row($q)){
$sql = mysql_query("UPDATE tableA SET user_id ='".$arr[$index++]."' WHERE code='".$codes[0]."'");
}
result perfect !
thanks all

MySQL: applying a random sort on multiple columns

In order to have a well scrambled table (for a psychological experiment), I'd like to sort each column of my array by RAND().
Althrough this code works:
SELECT Sort.Variable1, Sort.Variable2 FROM Sort ORDER BY Variable1, Variable2 ASC LIMIT 0 , 30
replacing "ASC" by "RAND()" make the query fail. Can someone give me an advice (even a solution with PHP) ?
Thanks
Edit:
Thanks to all your responses, I finally did it. Here's my PHP code for this (and sorry for the old-fashioned-not-brand-new-PDO-queries). Even if it's maybe useless, I post it:
$i=0;
//Describe to retrieve variables' names
$sqlCol= 'DESCRIBE Sort';
$sqlCol= mysql_query($sqlCol);
while ($res=mysql_fetch_array($sqlCol)) {
$var[$i]=$res['Field'];
$i++;
}
$NbCol=mysql_num_rows($sqlCol); //Number of column to shuffle
// Number of items for each column
$sqlCount= 'SELECT COUNT(*) FROM Sort';
$req2= mysql_query($sqlCount) or die ('Err');
$NbLignes= mysql_result($req2,0,0) or die ();//Number of rows
//Data array
$sql= "SELECT * FROM Sort";
$req= mysql_query($sql) or die ('Err');
$sort=mysql_fetch_array($req);
for($i=0;$i<$NbCol;$i++) {
${'sql'.$i}='SELECT * FROM Sort ORDER BY RAND()';
${'input'.$i} = mysql_query(${'sql'.$i});
while(${'array'.$i}=mysql_fetch_array(${'input'.$i})) {
$bigArray[$i][]=${'array'.$i}[$i];
}
}
for($i=0;$i<$NbLignes;$i++) {
echo '<div id="q'.$i.'"style="margin-bottom: 50px; float:left">Question '.($i+1);
echo '<ul id="sortable'.$i.'" class="sortable">';
for($j=0;$j<$NbCol;$j++) {
echo '<li class="ui-state-default" id="'.$var[$j].$i.'" name="'.$var[$j].$i.'">'. $bigArray[$j][$i].'</li>';
}
echo '</ul></div>';
}
Using ORDER BY RAND() won't randomize columns - it will randomize rows.
To randomize each column separately in SQL you can:
create a result set for each column separately
randomize the order of each of them
join the columns by row number
Unfortunately the MySQL development team haven't yet implemented ROW_NUMBER which would have made this task easy, but you can workaround it by simulating ROW_NUMBER using variables:
SELECT
Column1,
Column2
FROM
(
SELECT Column1, #rn1 := #rn1 + 1 AS rank
FROM Table1, (SELECT #rn1 := 0) vars
) T1
JOIN
(
SELECT Column2, #rn2 := #rn2 + 1 AS rank
FROM Table1, (SELECT #rn2 := 0) vars
ORDER BY RAND()
) T2
ON T1.rank = T2.rank
Here is one possible method to do what you want using PHP. In the example code, I generate a list of numbers and place them in an array. You will need to grab the list from your database.
<?php
// Create 20 rows.
$rows = 20;
// Create an empty array to hold sorted values.
$sort = array();
// Fill the array with ascending/descending numbers.
for ($i = 0; $i < $rows; $i++) {
$sort[$i]['var1'] = $i + 1;
$sort[$i]['var2'] = $rows - $i;
}
// Display the sorted array.
print "Sorted:\n";
print_rows($sort);
// Here's where the important bit happens:
// Create two arrays, each containing a list of the
// array keys from the sorted array (one for each column).
$var1 = array_keys($sort);
$var2 = array_keys($sort);
// Shuffle each list or array keys (one for each column).
shuffle($var1);
shuffle($var2);
// Create an empty array to hold shuffled values.
$shuffle = array();
// For every row in the list of shuffled keys, get
// the matching value from the sorted array, and
// place it in the shuffled array.
for ($i = 0; $i < $rows; $i++) {
$shuffle[$i]['var1'] = $sort[$var1[$i]]['var1'];
$shuffle[$i]['var2'] = $sort[$var2[$i]]['var2'];
}
// Display the shuffled array.
print "\nShuffled:\n";
print_rows($shuffle);
function print_rows($array) {
print "Row | Var 1 | Var2\n";
print "------------------\n";
foreach ($array as $key=>$row) {
printf("%3d | %5d | %4d\n", $key, $row['var1'], $row['var2']);
}
}
?>
Here's the output:
Sorted:
Row | Var 1 | Var2
------------------
0 | 1 | 20
1 | 2 | 19
2 | 3 | 18
3 | 4 | 17
4 | 5 | 16
5 | 6 | 15
6 | 7 | 14
7 | 8 | 13
8 | 9 | 12
9 | 10 | 11
10 | 11 | 10
11 | 12 | 9
12 | 13 | 8
13 | 14 | 7
14 | 15 | 6
15 | 16 | 5
16 | 17 | 4
17 | 18 | 3
18 | 19 | 2
19 | 20 | 1
Shuffled:
Row | Var 1 | Var2
------------------
0 | 8 | 2
1 | 19 | 12
2 | 14 | 5
3 | 16 | 17
4 | 2 | 8
5 | 11 | 4
6 | 7 | 11
7 | 9 | 10
8 | 12 | 1
9 | 5 | 9
10 | 13 | 20
11 | 10 | 6
12 | 17 | 19
13 | 18 | 18
14 | 4 | 14
15 | 20 | 7
16 | 3 | 16
17 | 15 | 15
18 | 6 | 3
19 | 1 | 13
The code is a bit rough and ready. I'm sure there are a number of ways in which it could be improved. For example, you could change it so the it is able to handle a variable number of columns. However, the basic idea is there.
Edit:
Here's a tidied up version of the code, which will handle a variable number of columns:
// Here's where the important bit happens:
// Create an empty array to hold shuffled values.
$shuffle = array();
// Get the name of each column (key) in the array.
foreach (array_keys($sort[0]) as $col) {
// Create an array of keys containing a list of the
// array keys from the sorted array.
$keys = array_keys($sort);
// Shuffle each list or array keys.
shuffle($keys);
// For every row in the list of shuffled keys, get
// the matching value from the sorted array, and
// place it in the shuffled array.
for ($i = 0; $i < $rows; $i++) {
$shuffle[$i][$col] = $sort[$keys[$i]][$col];
}
}
// Display the shuffled array.
print "\nShuffled:\n";
print_rows($shuffle);
You can do by 2 SQL statments:
SELECT Sort.Variable1 FROM Sort ORDER BY RAND(), Variable1 LIMIT 0 , 30
SELECT Sort.Variable2 FROM Sort ORDER BY RAND(), Variable2 LIMIT 0 , 30
if you need random in PHP array use: [array_rand][1]
<?php
// load all table values in array i just set them
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");
$rand_keys = array_rand($input, 2);
echo $input[$rand_keys[0]] . "\n";
echo $input[$rand_keys[1]] . "\n";
?>

Categories