I have this php code to do a query foreach loop going through the table name in variable $rowA but I got an "Array to string conversion" error. Does anyone know why? Can we do a query loop this way?
$sql = "SELECT `id`, `first_name` FROM `clients` ORDER BY `id` DESC";
$result = $DB_CON_C->query($sql);
$sql_email = "SELECT `email` FROM `clients` ORDER BY `id` DESC";
$account = $DB_CON_C->query($sql_email);
foreach($result as $row) {
foreach($account as $rowA) {
$stmt = "SELECT SUM(value) AS total_amount FROM `".$rowA."`";
$amount = $DB_CON_C->query($stmt);
$sum = $amount->total_amount;
$data_row .= '<tr>'
. '<td>' .$row['id'].'</td>'
. '<td>' .$row['first_name'].'</td>'
. '<td>' .$sum.'</td>';
}
}
}
$data_row .= '</tbody>'
. '</table>';
echo $data_row;
There seems to be a fundamentally odd issue with the way you are handling your data values.
Take your first query, $result, this will (obviously depending on the exact $DB_CON_C class method) output an array of values for id and first_name
Yet on the second call, $account using the same method you are then calling the values as if they're class variables $amount->total_amount.
I would suspect that one of these syntax is wrong, but without seeing your class I can't say which.
Do you realise that your two SQL calls are both returning the whole database?
Do you realise that you're using the data value (email address) in one table as the column name in another table? This can work, but this really isn't best practise.
You do not need to use the concaenator . for strings over new lines.
$string = "Hello
this string works fine";
as white space is reduced to one character length in HTML so it doesn't matter (much).
Solving your issue:
var_dump($account) once the value has been populated, same with $results, do var_dump($results) and see what is in the value, if these are class variables or arrays of data?
Seeing that both your variables are calling different parts of the same table, I have rewritten your code below:
$sql = "SELECT `id`, `first_name`, `email` FROM `clients` ORDER BY `id` DESC";
$result = $DB_CON_C->query($sql);
/***
* $result is assumed to be an array, within which is a set of values such as:
* $result[0]['id']
* $result[0]['first_name']
* $result[0]['email']
* $result[1]['id'], etc.
***/
foreach($result as $row) {
$stmt = "SELECT SUM(value) AS total_amount FROM `".$row['email']."`";
$amount = $DB_CON_C->query($stmt);
/***
* this is inconsistent, your data structure must be like $result as it
* uses the same methods, therefore you will need to enter the first
* "row" before getting the 'total_amount' value
***/
$sum = $amount[0]['total_amount'];
$data_row .= '<tr>
<td>' .$row['id'].'</td>
<td>' .$row['first_name'].'</td>
<td>' .$sum.'</td>
</tr>'; //you forgot your /tr !!
}
// Always clean up after foreach loops.
unset($row);
$data_row .= '</tbody>
</table>';
echo $data_row;
You're trying to parse a database row to a string, even though it contains only one thing.
Change the following line
$stmt = "SELECT SUM(value) AS total_amount "
. "FROM `".$rowA."`";
to
$stmt = "SELECT SUM(value) AS total_amount "
. "FROM `".$rowA['email']."`";
$rowA is a database row and contains the email field from the database.
Related
On my webpage (html, php), I'm trying to get it such that users may select multiple checkboxes, each checkbox effectively filters what results the users see. Info is pulled from the database (MySQL) based on the values in different columns. As shown below, one column is Joint_1, another column is Position.
Effective code that WORKS for filtering (very static, not practical to use obviously) is this:
$sql = "SELECT * FROM `Table_Name` WHERE (Joint_1=\'region1\' OR
Joint_1=\'region2\' OR
Joint_1=\'region3\' OR
Joint_1=\'region4\') AND
(Position=\'position1\' OR
Position=\'position2\' OR
Position=\'position3\')";
$result = $conn->query($sql);
if($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo $row["Common_Name1"] . "<br>";
}
} else {
echo "0 results";
}
Below code is attempts at above code, but using arrays, which does NOT work.
$regions =
array('region1', 'region2', 'region3', 'region4');
$position = array('position1', 'position2', 'position3');
$sql = "SELECT * FROM `Table_Name` WHERE (Joint_1=\'. $regions[0] .\' OR
Joint_1=\'. $regions[1] .\' OR
Joint_1=\'. $regions[2] .\' OR
Joint_1=\'. $regions[3] .\') AND
(Position=\'. $position[0] .\' OR
Position=\'. $position[0] .\' OR
Position=\'. $position[0] .\')";
Above code provides results of '0 results.'
I've attempted to perform this numerous times, with additional NON-FUNCTIONAL CODE also below (below attempting to filter based on only 1 column as I have obviously not mastered the code to approach filtering based on 2 columns).
$sqlregion = array();
foreach ($_POST['region'] as $reg) {
$sqlreg[] = "'" . mysql_real_escape_string($reg) . "'";
}
$sql = "SELECT * FROM 'Exercises' WHERE Joint_1 IN (" . implode(",",
$sqlreg) . ");";
$result=$conn->query($sql);
if($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo $row["Common_Name1"] . "<br>";
}
}
Any help is appreciated! Thanks.
You can construct this query from arrays, you can use the IN clause in mysql to specify multiple OR values
$regions = array('region1', 'region2', 'region3', 'region4');
$position = array('position1', 'position2', 'position3');
$regions = implode(",", $regions); // Converts array to string with comma as a separator
$position = implode(",", $position);
$sql = "SELECT * FROM `Table_Name` WHERE Joint_1 IN ($regions) AND Position IN ($position)";
echo $sql;
This gives you a query like this
SELECT * FROM Table_Name WHERE Joint_1 IN (region1,region2,region3,region4) AND Position IN (position1,position2,position3)
add in your own LIMIT GROUP BY or ORDER BY parameters to suit your needs
Purpose of this query is to retrieve a true image plus 3 random generated images from same table, then show them randomly. User(child) have to select correct image.
Thanks
$sql= "SELECT * FROM `login` WHERE `user` = '$word'";
" UNION"
"SELECT * FROM `login` WHERE `user` != '$word' ORDER BY RAND() LIMIT 3";
$row2=mysql_query($sql);
$i=1;
while ($r = mysql_fetch_array($row2))
{
echo '<td> ';
echo '<img src="sigg/'.$r['img'].'" width="130" height="130" /><br>';
echo $r['user'];
echo '</td>';
$i++;
}
Use the UNION clause:
$sql = "(SELECT * FROM `login` WHERE `user` = '$word')";
$sql.= " UNION";
$sql.= " (SELECT * FROM `login` WHERE `user` != '$word' ORDER BY RAND() LIMIT 3)";
$sql.= " ORDER BY RAND()";
To get the results you can use for example MySQLi (poseted before OP added his code with mysql_* functions):
$MySQL=new mysqli("localhost", "username", "password", "database");
$query = $MySQL -> query($sql);
while ($entry = $query -> fetch_row())
{
// $entry is an array with the results, use for example:
echo $entry[0]; // will return the first column of your table
echo $entry[1]; // will return the second column of your table
// try also:
var_dump($entry); // outputs everything for testing purposes
}
Please, don't use the mysql_* functions, they are deprecated and will be removed in the future versions of PHP. Use MySQLi or PDO instead. See Why shouldn't I use mysql_* functions in PHP? for more details.
Your request is not clear enough to provide a solid answer, so I'll try to answer it the best I can.
You should use Union in your query to get one big list of entries. However, just doing
SELECT * FROM `login` WHERE `user` = '$word'
UNION
SELECT * FROM `login` WHERE `user` != '$word' ORDER BY RAND() LIMIT 3
will give you a list of entries where user = $word in the first part and random 3 other entries.
As I said, I don't know the exact purpose of this, but I think you're better of querying the entire list from your database server.
Here's the php code:
$connection = mysql_connect(HOST, USER, PASSWORD);
mysql_select_db(DATABASE_NAME, $connection);
$sql = "SELECT img, user FROM `login` WHERE `user` = '{$word}' UNION SELECT img, user FROM `login` WHERE `user` != '{$word}' ORDER BY RAND() LIMIT 3";
$results = mysql_query($sql, $connection);
$rows = array();
// Insert results in a new array to shuffle it
while ($row = mysql_fetch_array($results)) {
$rows[] = array(
'img' => $row['img'],
'user' => $row['user']
);
}
shuffle ($rows); // Randomize order
// Construct HTML
$html = '';
foreach ($rows as $entry) {
$html .= '<td><img width="130px" height="130px" src="sigg/' . $entry['img'] . '">
$html .= $user . '</img></td>';
}
echo $html;
You will need to replace capitalized words with what's necessary.
A few explanations:
replace * with only what you need from tables (use fewer memory)
first insert results in an array so you can randomize the order (from MySQL you'll always have the first line the results from first query)
construct the html and output it all at once (executing multiple echo relies on the buffering to not send it to the browser, but that option might be off: What is output buffering).
I have an array $members that contains some ID(maximum 6 in number) from the table users. Using the following code, I loop through each index of $members, search for the details and store them in another array.
foreach($members as $key=>$value){
$res = mysql_query("SELECT id,name,email FROM users WHERE id='$value'");
if ($res === false) {
echo mysql_error();
die;
}
$row = mysql_fetch_assoc($res);
if($row['id'])
{
$members_name[]=$row['name'];//array for name
}
}
Now I want to insert the ID & names that are stored in the array into another TABLE register in the following format:
(The left side are the rows in my TABLE register)
mem_0_id-->$members[0]
mem_0_name-->$members_name[0]
mem_1_id-->$members[1]
mem_1_name-->$members_name[1]
mem_2_id-->$members[2]
mem_2_name-->$members_name[2]
mem_3_id-->$members[3]
mem_3_name-->$members_name[3]
mem_4_id-->$members[4]
mem_4_name-->$members_name[4]
How can I insert in this way? using just a single INSERT statement?
haven't tried this, but here is my answer anyway :)
$query = "INSERT INTO register(id, name) VALUES ($members[0], $members_name[0])";
for($i=1; $i<count($members); $i++)
{
$query .= ", ($members[$i], $members_name[$i])";
}
then try to execute the query..
Do you do anything else with the array, or are you just retrieving it from one table in order to insert it into another?
If so then you can do the whole thing like this.
$memberIds = implode(',', $members); // comma separated list of member ids
$query = "insert into register (id, name) select id, name from users where id in ($memberIds)";
mysql_query($query); // this will select and insert in one go
If you do need to keep the array in memory, then it's still a good idea to get it all out at once
$memberIds = implode(',', $members); // comma separated list of member ids
$query = "select id, name from users where id in ($memberIds)";
$res = mysql_query($query);
while ($row = mysql_fetch_assoc($res)) {
$memberData[] = $row;
}
That's because running a query inside a loop is very bad for performance. Every time you run a query there is an overhead, so getting all the data at once means you pay this overhead once rather than multiple times.
Then you can build a statement to insert multiple rows:
$sql = "insert into register (id, name) values ";
$sql .= "(" . $memberData[0]['id'] . "," . $memberData[0]['name'] . ")";
for($i = 1; $i < count($memberData); $i++) {
$sql .= ",(" . $memberData[$i]['id'] . ",'" . $memberData[$i]['name'] . "')";
}
mysql_query($sql);
It's a bit nasty because of the commas and quotes but if I've done it correctly then if you do
echo $sql;
you should get something like
insert into register (id, name) values (1, 'john'), (2, 'jane'), (3, 'alice');
You can see that the first way, where you select and insert in one statment, is a lot nicer and easier so if you don't do anything else with the array then I highly recommend doing it that way.
It is possible to include PHP data in a MySQL result? Let me explain myself:
Two tables, one with user's actions and one with user information. I'd query the actions and retrieve the user IDs and count each one grouped by user:
$ids = $conn->fetchAll('SELECT origin,COUNT(*) as actions from action WHERE `brand` = ' . $id . ' AND SUBSTRING(origin,1,3)<>"pct" GROUP BY origin');
Then I take that result array and use it to input the user info from another table:
$norm_ids = '(';
foreach ($ids as $ids) {
$norm_ids .= $ids['origin'] .',';
}
$norm_ids = substr_replace($norm_ids ,"",-1) .')';
$users = $conn->fetchAll('SELECT * from userinfo WHERE `id` in ' . $norm_ids . ' ORDER BY `name`');
I want in $users to include the COUNT(*) I got in the previous query, is that possible directly on the query?
I have made my own script, i guess this is what you are looking for:
$sql = "SELECT * FROM user WHERE Username = '".$_SESSION['Username']."' ";
$stm = $db->prepare($sql);
$result = $stm->execute(array());
while($row = $stm->fetch(PDO::FETCH_ASSOC)) {
$userid = $row['UserID'];
}
here i get the users id
$sql = "SELECT activity.*"."FROM user_activity, activity "."WHERE user_activity.ActivityID = activity.ActivityID AND user_activity.UserID = '".$userid."' " ;
and here u use the $userid in my query.
You can use a mysql join for that:
SELECT u.*, count(a.origin) FROM userinfo AS u LEFT JOIN action AS a ON a.origin = u.id WHERE a.brand = '.$id.' AND SUBSTRING(a.origin,1,3) <> "pct" GROUP BY a.origin
You'll have to try and tweak it a little bit (probably) but it might make your script a lot easier. (I'm not sure whether userinfo will be grouped together too or not(probably shouldn't)).
When using a JOIN you'll have to set correct indexes for maximum performance though.
First of all, a few comments on the code in general:
foreach ($ids as $ids)
This just looks wrong, I don't know how PHP handles this but probably not as you would expect it. Use a different variable name, just for clarity's sake.
You need to escape the quotes around "pct" in the query so they're not parsed by PHP.
Also, I don't know where the $id comes from in the first SQL statement, but you might want to escape it. Using PDO:
$stmt = $conn->prepare("SELECT origin,COUNT(*) as actions from action WHERE `brand` = :id AND SUBSTRING(origin,1,3)<>\"pct\" GROUP BY origin");
$stmt->execute( array( ":id" => $id ) );
$ids = stmt->fetchAll();
To access the COUNT(*) data and add it to the user info, I'ld first rename it in the first query (don't like special characters in my array keys):
"SELECT origin,COUNT(*) as nummatches as actions from action WHERE `brand` = :id AND SUBSTRING(origin,1,3)<>\"pct\" GROUP BY origin"
Then, you can add it to the SELECT part of your statement in the second query:
'SELECT *,' . $ids['nummatches'] . ' from userinfo WHERE `id` in ' . $norm_ids . ' ORDER BY `name`'
I have a search script that retrieves an integer from one table and uses it to search through the IDs of a 2nd table. My issue is if the integer in Table1 appears more then once, I get duplicate results when querying Table2.
Does anyone know a way to use SQL or PHP so that if a row is already displayed it will skip it? Thanks
My code is rather convuleted but here it is if it helps:
//TV FILTERS
$sql = 'SELECT * FROM `table1`';
$where = array();
if ($searchlocation !== 'Any') $where[] = '`value` LIKE "%'.$searchlocation.'%"';
if ($searchmake !== 'Any') $where[] = '`value` LIKE "%'.$searchmake.'%"';
if ($searchtype !== 'Any') $where[] = '`value` LIKE "%'.$searchtype.'%"';
if (count($where) > 0) {
$sql .= ' WHERE '.implode(' OR ', $where);
} else {
// Error out; must specify at least one!
}
$tvqresult = mysql_query($sql);
$num_rowstvq = mysql_num_rows($tvqresult);
while ($rowtvq = mysql_fetch_array($tvqresult)) {
$contid = $rowtvq['contentid'];
//MAIN QUERY
$mainsql = 'SELECT * FROM `table2` WHERE `content` LIKE "%' . $searchterm . '%" AND `id` = ' . $rowtvq['contentid'] . ' AND `template` = 12';
$resultmain = mysql_query($mainsql);
$num_rowsmain = mysql_num_rows($resultmain);
if (!$resultmain) {
continue;
}
else {
while ($row = mysql_fetch_array($resultmain )) {
echo "[!Ditto? &parents=`134` &documents=" . $row['id'] . "&tpl=`usedtempchunk`!]";
}//END MAIN LOOP
}//END MAIN ELSE
}//END TV WHILE LOOP
You only seem to use the contentid column from your first query, so you could change it to:
$sql = 'SELECT distinct contentid FROM `table1`'; // rest would be the same
which would mean that no duplicates will be retreived saving you any hassle in changing your second set of code.
If you are using other columns from the first query somewhere else in your code, you can still fetch more columns with this method as long as there are no duplicate IDs:
$sql = 'SELECT distinct contentid, contentTitle, contentThing FROM `table1`';
If you have to have repeated IDs in your original query, I think you will have to store the data in a variable (like an array) and then make sure that the second dataset isn't repeating anything.
It sounds like you're only looking for 1 row, if so, then at the end of your SQL, simply add LIMIT 1. That'll ensure you only return 1 row, thereby ignoring any duplicate matches.