SQL query returns one row too few - php

SOLUTION: Make sure you don't 'use up' any $responses->fetch_assoc()s before the while loop.
I performed mysqli_fetch_array($responses);.
In php I have this sql query (simplified for your convenience, but the problem remains)
$sql = "SELECT id, content FROM responses ORDER BY RAND()";
$responses = $conn->query($sql);
where the responses table looks like this:
+----+----------+--------+------+
| id | content | userId | part |
+----+----------+--------+------+
| 4 | peewee | 31 | 1 |
| 5 | tallinn | 31 | 1 |
| 6 | dewey | 31 | 1 |
| 7 | stanford | 31 | 1 |
+----+----------+--------+------+
That doesn't format properly so all you need to know is that the id and content rows are different for each entry while the rest is the same for each.
The problem is, when I do a while loop on $responses like so:
while ($row = $responses->fetch_assoc()) {
$responseId = $row["id"];
$content = $row["content"];
echo " id: ".$responseId;
echo " content: ".$content;
}
I always get 1 record fewer than there are. In this case, since there are 4 rows, I would only see 3 echoed. However, it is not always the same 3, nor are they in the same order. If I remove the ORDER BY RAND() clause, then it is always the first record which is left out.
Thanks in advance
Cheers

Related

Querying MySQL results into multi-dimensional associative PHP array

I'm probably overlooking a fairly simple way of doing this; perhaps someone has an idea of how to make this easy with limited looping and without an excessively long query. Let's say I have a MySQL table with data like this: (There's 12 months, and could be maybe 10 different possible grades). I'll query out just the results for a given user_id and year.
+----+---------+------+-------+-------+-------+
| id | user_id | year | month | grade | value |
+----+---------+------+-------+-------+-------+
| 1 | 1 | 2021 | Jan | A | 95 |
+----+---------+------+-------+-------+-------+
| 2 | 2 | 2021 | Jan | D | 75 |
+----+---------+------+-------+-------+-------+
| 3 | 2 | 2021 | Feb | F | 45 |
+----+---------+------+-------+-------+-------+
I want to be able to query the data and put it into a multi-dimensional associative PHP array.
Essentially, so I can access the data like this:
echo $month_value['Jan']['D']; // Should give me 75
echo $month_value['Feb']['F']; // Should give me 45
Figured out a simple method that works for me:
$sql_retrieve = $con->prepare("SELECT month, grade, value
FROM table
WHERE user_id = ? AND year = ?;");
$bind_process = $sql_retrieve->bind_param('ii',$user_id,$year);
$sql_retrieve->execute();
$result = $sql_retrieve->get_result();
$month_values = []; // initialize array
if($result->num_rows > 0 ){ // If there are results
while($row=$result->fetch_assoc()){
$month_values[$row["month"]][$row["grade"]] = $row["value"]; // add to array
} // end while
} // end of if num_rows > 0
print_r($month_values); // Example
echo 'Value: '.$month_values['Jan']['D'];
This then provides the MySQL results into a multi-dimensional associative PHP array, so they can be referenced as such.

do the math for each data in database sql post result to database in php

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?

How do I get rollup count 'Total' in table

I have created a table in the database which displays Date, User, Value. The following is a revised design:
Date | User | Value
---------- | ----- | -----
So each user has a count of what submissions they have done matching via the date. The results are displayed from this query from the database
SELECT * FROM testreport
Please see the new design below as mentioned from the comments, I have added the row total at the end.
Date | User1 | User2 | User3 | Value
---------- | ----- | ----- | ----- | -----------
23-02-2017 | 2 | 5 | 9 | 16
24-02-2017 | 5 | 7 | 11 | 23
25-02-2017 | 6 | 13 | 1 | 20
But what I am trying to achieve is by selecting the table and have total to show in the last row like this, how do I go about doing this:
Date | User1 | User2 | User3 | Value
---------- | ----- | ----- | ----- | -----------
23-02-2017 | 2 | 5 | 9 | 16
24-02-2017 | 5 | 7 | 11 | 23
25-02-2017 | 6 | 13 | 1 | 20
Total | 13 | 25 | 21 | 59
but I cannot specify the column names like How do I calc a total row using a PIVOT table, without UNION, ROLLUP or CUBE?. Because from time time there will be extra users added to this table but I want to be able to get all the columns with totals at the end. On my site I am using PHP to display the table on the page with the code:
$sqlres = "SELECT * FROM testreport order by Date DESC ";
$resultsql = mysqli_query($sqlres) or die(mysql_error());
echo "<table><tr>";
for($i = 0; $i < mysqli_num_fields($resultsql); $i++) {
$field_info = mysqli_fetch_field($resultsql, $i);
echo "<th>{$field_info->name}</th>";
}
// Print the data
while($rows = mysqli_fetch_row($resultsql)) {
echo "<tr>";
foreach($rows as $_column) {
echo "<td>{$_column}</td>";
}
echo "</tr>";
}
echo "</table>";
Which displays the headers and rows as I wanted them to be and any new user I add to the 'testreport' table column it automatically adds an extra column on the page, how do I go about achieving the rollup of these columns to get total.
Any help on this would be appreciated.

Is it possible to sort Array Value with Array Value?

I have an example like this:
code | name
a | Pencil
b | Pen
d | Ruler
g | TipeX
-
no | data | list_order
1 | b,d,a | 2,3,1
2 | g,b,a | 3,2,1
So when run the query the data will be like this:
no | data | list_order
1 | b | 2
1 | d | 3
1 | a | 1
Then I can sort it by list_order ASC
no | data | list_order
1 | a | 1
1 | b | 2
1 | d | 3
My question, is it possible to get the query like above?
*I'm using Oracle DB
$q_data = oci_parse($c1, "SELECT * FROM DATAS WHERE NO = '1'");
oci_execute($q_data);
$row = oci_fetch_array($q_data);
$cp_array = implode(",",array($row['data']));
$cp_list_order = implode(",",array($row['list_order']));
$q_data_cp = oci_parse($c1, "SELECT * FROM DATAS_DTL WHERE no IN ($cp_array)");
oci_execute($q_data_cp);
while($d_data = oci_fetch_array($q_data_cp))
{
$d_no = $d_data['no'];
$d_name = $d_data['name'];
?>
<div><?php echo $d_name; ?></div>
<?php
}
Thanks.
I don't use oracle db, but I use sql server and I think they both are similar in a lot of ways.
Try to do the following:
create a temp table
split the string using some kind of CROSS APPLY (see: How to split a comma-separated value to columns)
insert the splitted values inside the temp table
query the temp table

Adding mysql entries together and displaying them in a table

My data (simplified) looks like....
------------------------
| key | id | minspld |
------------------------
| 1 | 400 | 90 |
| 2 | 400 | 40 |
| 3 | 401 | 38 |
| 4 | 401 | 90 |
| 5 | 402 | 90 |
| 6 | 402 | 89 |
| 7 | 403 | 77 |
| 8 | 403 | 15 |
| 9 | 404 | 90 |
-----------------------
I am trying to do....
For each id, add all their minspld entries together
Display them in a table like above, but each id only showing once, and the minspld column showing the total per each id.
Here's what I'm using at the moment and I'm displaying all entries separately (eg, each person shows twice)
<table><thead><tr><th>ID</th><th>Mins Played</th></tr></thead>
<tbody>
<?php
$queryget = mysql_query("SELECT * FROM mlsstats ORDER BY id ASC") or die(mysql_error());
while ($row = mysql_fetch_assoc($queryget))
{
$id = $row['id'];
$minspld = $row['minspld'];
echo "<tr>";
echo "<td>".$id."</td>";
echo "<td>".$minspld."</td>";
echo "</tr>";
}
?>
</tbody></table>
How would I write this to make each id show only once in the HTML, but with the added totals of all their minspld entries? (eg, id 400 would have 130. id 401 would have 128. etc.)
If this isn't clear, please let me know.. and thanks for any help.
Please try changing your query to:
SELECT id, SUM(minspld) AS minspld FROM mlsstats GROUP BY id ORDER BY id ASC
You dont have to use a loop for this. You can simply do this with query
Just run the query and get two columns. id and its total
SELECT
m.id,
SUM(minspld) AS TCount
FROM mytable AS m
GROUP BY m.id

Categories