I have some lines of data on a table as shown below :
+-------------------+-------+
| criteria | value |
+-------------------+-------+
| Pengalaman Kerja | 4 |
| Pendidikan | 3 |
| Usia | 5 |
| Status Perkawinan | 2 |
| Alamat | 6 |
| Pengalaman Kerja | 3 |
| Pendidikan | 1 |
| Usia | 4 |
| Status Perkawinan | 2 |
| Alamat | 1 |
+-------------------+-------+
10 rows in set (0.00 sec)
I tried to fetch them all in PHP using fetch_object() and then convert the returned data into arrays and sum the values of each criteria listed on the table.
example : Pengalaman kerja has two values (4 and 3) so the result for Pengalaman Kerja array will be 7.
$result = $db->query($sql);
$value = array();
while($row=$result->fetch_object()){
if(!isset($value[$row->criteria]){
$value[$row->criteria] = 0;
})
$value[$row->criteria] += $row->value;
var_dump($value);
}
When I ran var_dump to $value (which is now contains summed value of each criteria) it showed me :
array(5) {
["Pengalaman Kerja"]=>
int(7)
["Pendidikan"]=>
int(4)
["Usia"]=>
int(9)
["Status Perkawinan"]=>
int(4)
["Alamat"]=>
int(6)
}
Pengalaman kerja is correct because 4 + 3 = 7
Pendidikan is correct because 3 + 1 = 4
Usia is correct because 5 + 4 = 9
Status Perkawinan is correct because 2 + 2 = 4
And the wrong thing is Alamat showing 6 that it should be 7 because 6 + 1 = 7
I'm sure it was because one of Alamat record was on the last of lines and the while() function didn't count until the last of lines.
While() function only counted to the last - 1
How can I solve this problem so Alamat shows 7 as it is suppossed to show ?
Why even bother doing this in PHP? If you just want the sum of all rows grouped by criteria then do it with a simple MySQL query?
SELECT criteria, SUM(value) AS total FROM table GROUP BY criteria
EDIT: If you insist on doing it your way then aside from a couple of typos in your code, which would usually cause runtime errors, your code should work as expected. When I run it against a table with the exact same data I get the expected results.
BTW, PDOStatement has no method called fetch_object (this is the name of the helper function) so if you want to use a method to fetch the query results as an object for a PDOStatement you have to use the proper name which is fetchObject().
PHP
$result = $dbh->query("SELECT * FROM test");
$value = array();
while ($row = $result->fetchObject()) {
if (!isset($value[$row->criteria])) {
$value[$row->criteria] = 0;
}
$value[$row->criteria] += $row->value;
}
var_dump($value);
Results
array (size=5)
'Pengalaman Kerja' => int 7
'Pendidikan' => int 4
'Usia' => int 9
'Status Perkawinan' => int 4
'Alamat' => int 7
Related
I'd like to fetch data from my 2 sql database and do some math and post the result in database
let's say my table1 is like this
+---+---+----------------------------+
| A | B | C |
+---+---+----------------------------+
| 2 | 9 | result from A*B*D*E in php |
| 1 | 8 | result from A*B*D*E in php |
| 4 | 7 | result from A*B*D*E in php |
| 3 | 6 | result from A*B*D*E in php |
| 6 | 5 | result from A*B*D*E in php |
| 6 | 5 | result from A*B*D*E in php |
| 5 | 4 | result from A*B*D*E in php |
+---+---+----------------------------+
and my table2 is like this
+---+----+
| D | E |
+---+----+
| 1 | 9 |
| 2 | 7 |
| 3 | 8 |
| 4 | 6 |
| 5 | 5 |
| 6 | 3 |
| 7 | 2 |
+---+----+
so far what i've done
// database connection
include_once("config.php");
// Query
$query = mysqli_query($conn, "SELECT * FROM table1");
$query2 = mysqli_query($conn, "SELECT * FROM table2");
//Source1
while($user_data1 = mysqli_fetch_array($query))
{
$A[] = $user_data1['A'];
$B[] = $user_data1['B'];
}
//Source2
while($user_data2 = mysqli_fetch_array($query2))
{
$D[] = $user_data2['D'];
$E[] = $user_data2['E'];
}
foreach (array_combine($A, $B) as $ValueA=> $ValueB)
{
foreach (array_combine($D, $E) as $ValueD=> $ValueE)
{
$result1 = $ValueA*$ValueB*ValueD*ValueE;
$val = 0.123;
$result2[] = $result1*$val;
}
$final result = min($result2);
echo round($final result, 2);
unset($result2);
}
I haven't inserted the database yet
still echoing for debug if the math is correct
somehow this code found some bug
for example using my database the final result only echo/showing 6 math result
because in table1 row 5 and 6 has same data
btw of course in my table1 and 2 has primary key
To change C in this case, you don't even need PHP. To UPDATE a value in MySQL with multiple tables just add them with a , when selecting the tables, like this:
UPDATE table1,table2 SET C = table1.A * table1.B * table2.D * table2.E WHERE C IS NULL;
Executing this code once will update all rows so that C = A*B*D*E as wanted where C is not yet set or NULL. If you want to update all rows you can just remove the WHERE condition
Note: Sometimes (at least for me) SQL will give a warning when having no WHERE condition in the SQL query. To bypass this just add WHERE 1=1 at the end.
Just for my understanding: you want to calculate a value for your calculation you need some data from table 1 that is clear, but also from table2 But which one? I guess you want to use the data from the same row ( so row 1 from table1 and row 1 from table2, row 2 from table 1 and row 2 from table2 ) right? Now you have an problem because when you make a select * from table You do not know in which order they give back from your database. Most time it may be the same order as you have input them, but there is no garantie. You have sayed you have an primary key on each table, how have you defined them? I guess you may have a id column, so you can join your table on that id?
-----------------------------------------------------
| id | posts_id | users_id | ratings |
-----------------------------------------------------
| 1 | 7 | 20 | 5 |
| 2 | 8 | 20 | 3 |
| 3 | 7 | 21 | 4 |
-----------------------------------------------------
Table name: mytable
\I want to make sure that ratings between posts_id and users_id are matched on the same column.
$query = $conn->query("SELECT ratings FROM mytable WHERE posts_id=7 and users_id=20");
$row = $query->fetch_array();
echo $row['ratings'];
This query does not work. I know there must be something wrong.
I want to get results: 5
What is the best query to show ratings?
----------------UPDATE-----------------------------
Sorry, my first problem lies with the connection, and now it is resolved.
But now there is a new problem.
I want to display the total sum of the rating results.
My new code
$Rate = $conn->query("SELECT * FROM mytable WHERE posts_id=7");
while ($Rated = $Rate->fetch_array()) {
echo $Rated['ratings'] + $Rated['ratings'];
}
For example on posts_id=7
Here I expect 5 + 4 = 9
But my code results exactly 54 + 54
How to fix this code?
For the updated question, this code should be work. We can use sum() function. Check here sum() function
$Rate = $conn->query("SELECT sum(ratings) as ratings FROM mytable WHERE posts_id=7");
while ($Rated = $Rate->fetch_array()) {
echo $Rated['ratings'];
}
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
I insert multiple id from my checkbox to MySQL database using php post form. In example I insert id (checkbox value table test) to mysql. Now I need a function to retrieve data from MySQL and print to my page with my example output (print horizontal list name of table test where data = userid)
My checkbox value (table name is test):
id | name
----+-------
1 | test1
2 | test2
3 | test3
4 | test4
5 | test5
6 | test6
7 | test7
9 | test9
MySQL data insert (name of table usertest):
id | data | userid
----+---------+--------
1 | 1:4:6:9 | 2
2 | 1:2:3:4 | 5
3 | 1:2 | 7
Example outout :( print horizontal list name of table test where data = userid )
user id 2 choise : test1 - test4 - test6 - test9
Thanks
Assuming your usertest table has only the three columns listed in your example you should replace it with the following -
CREATE TABLE usertest (
data INTEGER NOT NULL,
userid INTEGER NOT NULL,
PRIMARY KEY (data, userid)
);
Then your data will look like -
+------+--------+
| data | userid |
+------+--------+
| 1 | 2 |
| 4 | 2 |
| 6 | 2 |
| 9 | 2 |
| 1 | 5 |
| 2 | 5 |
| 3 | 5 |
| 4 | 5 |
| 1 | 7 |
| 2 | 7 |
+------+--------+
Querying this data then becomes trivial -
SELECT usertest.userid, GROUP_CONCAT(test.name SEPARATOR ' - ')
FROM usertest
INNER JOIN test
ON usertest.data = test.id
GROUP BY usertest.userid
You can read more about GROUP_CONCAT here
You could use a PHP solution and store the possible checkbox values in an array indexed by their ids. Something like -
<?php
$db = new PDO('mysql:dbname=test;host=127.0.0.1', 'user', 'pass');
$sql = 'SELECT id, name FROM test';
$stmt = $db->prepare($sql);
$stmt->execute();
$array = array();
while ($row = $stmt->fetchObject()) {
$array[$row->id] = $row->name;
}
$sql = 'SELECT userid, data FROM usertest';
$stmt = $db->prepare($sql);
$stmt->execute();
while ($row = $stmt->fetchObject()) {
$data = explode(':', $row->data);
foreach($data as $key => $val) {
$data[$key] = $array[$val];
}
print "user id {$row->userid} choise : " . implode(' - ', $data) . "<br/>\n";
}
For instance, if I have the following table:
+----+---+----------+
| id | a | position |
+----+---+----------+
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 2 | 1 | 4 |
| 3 | 1 | 9 |
| 4 | 1 | 6 |
| 5 | 1 | 1 |
+----+---+----------+
and I want to get an array that contains the first 100 values from position where a is 1 in ascending order, what would I do?
Im guessing something like this:
$col = mysql_fetch_array( mysql_query('
SELECT `position`
FROM `table`
WHERE `a`="1"
ORDER BY `position` ASC
LIMIT 100
'));
I'd expect to get the following array:
+-------+-------+
| index | value |
+-------+-------+
| 0 | 1 |
| 1 | 4 |
| 2 | 6 |
| 3 | 9 |
+-------+-------+
but it doesn't work.
¿What should I do to make it work?
Thanks
mysql_fetch_array() gets a single row at a time from the result of your query. To access all of the rows you need a loop. Something like...
while ($row = mysql_fetch_array($result, MYSQL_NUM))
{
printf("index: %s value: %s", $row[0], $row[1]);
}
I would take a closer look at: http://php.net/manual/en/function.mysql-fetch-array.php
Okay, couple of things:
Running the mysql_query inside the fetch_array is weird. Mysql_fetch_array works on a query result to put the individual lines of the result(as fetched) into an array. So when you're running it as you've got it, if it runs at all, it's only going to give you the first row, not the first hundred rows.
Second, the quoting looks pretty weird. Depending on the data type in "a", the double quotes might cause. (Haven't used MySQL in a bit, could be wrong.)
If I was going to do it, I'd do it like this:
$result = mysql_query("SELECT index, position FROM table WHERE a = 1 ORDER BY position ASC LIMIT 100");
while($col = mysql_fetch_array($result)){
*do something*
}
*Thanks to JYelton for the Query reformat.
Your query is okay.
The problem is that mysql_fetch_array retrieves only one row. You should loop all the rows and add each value to your $col array.
$result = mysql_query('...');
while($row = mysql_fetch_array($result, MYSQL_NUM))
{
$col[] = $row[0];
}
Now $col contains following:
Array
(
[0] => "1"
[1] => "4"
[2] => "6"
[3] => "9"
)