So I am trying to have a single script that accesses all values of a table based on a particular id. The script returns the values in an array using PHP:
Example:
// Select data from DB
$query = 'SELECT * FROM experiences WHERE user_id = ' . $id;
$result = mysqli_query($link, $query) or die (mysqli_error($link));
// Not sure this actually creates a 2D array...
$array = mysqli_fetch_array($result);
However, I realize that I need modified results for particular tasks, such as the row where a particular value is the highest.
How would I go about doing this, and does $array actually hold all the rows and respective fields?
TRY
'SELECT * FROM experiences WHERE user_id ='.$id.' HAVING MAX(column_name)
OR
"SELECT max(column_name), other column...
FROM experiences
WHERE user_id =".(int)$id
Assuming you have cleaned $id properly you can do this
// Select data from DB
$query = 'SELECT * FROM experiences WHERE user_id = ' . $id;
$result = mysqli_query($link, $query) or die (mysqli_error($link));
$data = array();
while($row = mysqli_fetch_array($result)) {
$data[] = $row;
}
and $data will contain the 2D array you're looking for.
If you want the row where a particular value is highest I suggest either looking into ORDER BY or MAX() depending on your needs.
Related
This query returns 13 individual arrays:
$array = array($pgff_id, $pgfm_id, $pgmf_id, $pgmm_id, $mgff_id, $mgfm_id, $mgmf_id, $mgmm_id, $pgf_id, $pgm_id, $mgf_id, $mgm_id, $fid, $mid);
foreach($array as $id) {
$stmt = $db->prepare("SELECT birth_year, death_year FROM index WHERE id = ?");
$stmt->execute([$id]);
$data = $stmt->fetch(PDO::FETCH_ASSOC);
print_r shows that they look like this:
Array ([birth_year] => 1750 [death_year] => 1824)
Array ([birth_year] => 1770 [death_year] => 1836)
... etc
Is it possible to assign a number or name to these individual arrays? The results are not useful without a way to identify them.
I tried doing it like shown below. This way does number the arrays but orders the results as they are found in the table. I really need the results ordered as they are in $array (which the first method does manage).
$in = str_repeat('?,', count($array) - 1) . '?';
$sql = "SELECT birth_year, death_year FROM index WHERE id IN ($in)";
$stmt = $db->prepare($sql);
$stmt->execute($array);
$data = $stmt->fetchAll();
Taking your code and adding in id as an expression in the query would result in this:
$in = str_repeat('?,', count($array));
$sql = "SELECT id, birth_year, death_year FROM index WHERE id IN ($in)";
$stmt = $db->prepare($sql);
$stmt->execute($array);
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
echo "here starts another row:<br>";
echo "id = ".$row["id"]."<br>";
echo "birth_year = ".$row["birth_year"]."<br>";
echo "death_year = ".$row["death_year"]."<br>";
}
So, that's how you can access it.
You can rearrange the data in the rows after you've received them from the database, again by using a foreach loop:
$birth = [];
$death = [];
foreach ($rows as $row) {
$id = $row["id"];
$birth[$id] = $row["birth_year"];
$death[$id] = $row["death_year"];
}
Now you can access both arrays to get the birth or death year based on the id like this:
echo $birth[4]. 'and '. $death[4];
where id is 4.
In order to validate the integrity of data entered into forms by users, one test I must perform is to ensure that the data does not exceed the length of the table column that will hold it. Rather than hard-coding in the maximum length values for the various columns in my tables, I thought it would be more efficient to write a routine that would gather all the relevant constraint information from my tables (here, just the data_type and character_maximum_length) and put it into an associative array in which I could simply retrieve the values with easily writable and readable:
$table_info_array[$table_name][$column_name]['character_maximum_length'];
I found a solution, and it works rapidly on my localhost, but the construction of the $table_info_array is unacceptably slow on my live server. Here is what I coded:
/* Skipped here: set up your PDO $connection first, then: */
// Define your database:
$database_name = "my_database";
$sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '" . $database_name ."'";
$stmt = $connection->prepare($sql);
$result = $stmt->execute();
$counter = -1;
$table_array = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
foreach ($row as &$value) {
$counter++;
$table_array[$value] = $counter;
}
}
$table_info_array = array();
foreach ($table_array as $table_name => $table_value) {
// Here I'm selecting the data_type and character_maximum_length by column_name, but other information could easily be collected:
$sql = "SELECT column_name, data_type, character_maximum_length FROM information_schema.columns WHERE table_name = '" . $table_name . "'";
$stmt = $connection->prepare($sql);
$result = $stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$table_info_array[$table_name][$row['column_name']]['data_type'] = $row['data_type'];
$table_info_array[$table_name][$row['column_name']]['character_maximum_length'] = $row['character_maximum_length'];
}
}
This will show everything; notice how concise the results are:
print_r($table_info_array);
The syntax for retrieving table column constraints is therefore:
$table_info_array[$table_name][$column_name]['data_type'];
$table_info_array[$table_name][$column_name]['character_maximum_length'];
For example, now I can retrieve the maximum character length on the 'title' column in my 'artwork' table, like this:
$table_info_array['artwork']['title']['character_maximum_length'];
The construction of the $table_info_array works at lightning speed on my localhost, but on my live server it is unreasonably slow. Is there a faster way to do this?
I've been trying to display the number of rows using this code but it keep says
1 Rows which is wrong
<?php
$link = mysql_connect("localhost", "gamin1_forum", "password123");
mysql_select_db("gamin1_forumdb", $link);
$result = mysql_query("SELECT COUNT(*) FROM smf_personal_messages", $link);
$num_rows = mysql_num_rows($result);
echo "$num_rows Rows";
?>
Rows are approximately 1443 but it kept saying 1
The Count(*) returns you one row which contains the number of rows as a value.
By using mysql_num_rows($result) you are actually counting the amount of rows of the Count(*) result which really is one.
Change it to:
$result = mysql_query("SELECT * FROM smf_personal_messages", $link);
$num_rows = mysql_num_rows($result);
Or just use the Count(*) value (which is probably better since it count in the DB and not retrieving the whole table for it) using mysql_fetch_array.
This is true, mysql_num_rows() is telling that there was one "row" returned. You need to check the value of the returned row to get your count. Try this
$link = mysql_connect("localhost", "gamin1_forum", "password123");
$result = mysql_query("SELECT COUNT(*) as cnt FROM smf_personal_messages", $link);
$row = mysql_fetch_array($result);
echo ($row['cnt']);
On a side note, you should not use mysql_* functions for security reasons. Try PDO/mysqli_* functions
I want to find out how many rows are in a table. The database that I am using is a MySQL database. I already have a Db_Table class that I am using for calls like fetchAll(). But I don't need any information from the table, just the row count. How can I get a count of all the rows in the table without calling fetchAll()?
$count = $db->fetchOne( 'SELECT COUNT(*) AS count FROM yourTable' );
Counting rows with fetchAll considered harmful.
Here's how to do it the Zend_Db_Select way:
$habits_table = new Habits(); /* #var $habits_table Zend_Db_Table_Abstract */
$select = $habits_table->select();
$select->from($habits_table->info(Habits::NAME), 'count(*) as COUNT');
$result = $habits_table->fetchRow($select);
print_r($result['COUNT']);die;
Proper Zend-Way is to use Zend_Db_Select like this:
$sql = $table->select()->columns(array('name', 'email', 'status'))->where('status = 1')->order('name');
$data = $table->fetchAll($sql);
$sql->reset('columns')->columns(new Zend_Db_Expr('COUNT(*)'));
$count = $table->getAdapter()->fetchOne($sql);
This is how it's done in Zend_Paginator. Other option is to add SQL_CALC_FOUND_ROWS before your column list and then get the number of found rows with this query:
$count = $this->getAdapter()->fetchOne('SELECT FOUND_ROWS()');
You could do a
SELECT COUNT(*)
FROM your_table
$dbo->setFetchMode( Zend_Db::FETCH_OBJ );
$sql = 'SELECT COUNT(*) AS count FROM #table';
$res = $dbo->fetchAll( $sql );
// $res[0]->count contains the number of rows
I'm kind of a minimalist:
public function count()
{
$rows = $db->select()->from($db, 'count(*) as amt')->query()->fetchAll();
return($rows[0]['amt']);
}
Can be used generically on all tables.
Add count capability to your Zend_DB Object To count all table rows
public function count()
{
return (int) $this->_table->getAdapter()->fetchOne(
$this->_table->select()->from($this->_table, 'COUNT(id)')
);
}
I want to display four (4) items'name from these id:
Can I do like this?
SELECT item_name from items WHERE item_id IN ('001', '012', '103', '500')
or
SELECT item_name from items WHERE item_id = '001' or item_id = '012' or item_id = '103' or item_id = '500'
IN RESPONSE TO ALL ANSWERS
Well, most of the answers said it works, but it does not really work. Here is my code:
$query = "SELECT `item_name` from items WHERE item_id IN('s001','a012','t103','p500')";
$result = mysql_query($query, $conn) or die (mysql_error());
$fetch = mysql_fetch_assoc($result) or die (mysql_error());
$itemsCollected = $fetch['item_name'];
echo $itemsCollected;
The item_id is alphanumeric.
You can do either one, but the IN query is much more efficient for this purpose for any large queries. I did some simple testing long ago that revealed it's about 10 times faster to use the IN construct for this. If you're asking if the syntax is correct then yes, it looks fine, other than missing semi-colons to complete the statement.
EDIT: It looks like the actual question you were asking was "why do these queries only return one value". Well, looking at the sample code you posted, the problem is here:
$fetch = mysql_fetch_assoc($result) or die (mysql_error());
$itemsCollected = $fetch['item_name'];
echo $itemsCollected;
You need to loop through and iterate until there are no more results to be fetched, as Pax pointed out. See the PHP manual page for mysql_fetch_assoc:
$sql = "SELECT item_name from items WHERE item_id IN('s001','a012')";
$result = mysql_query($sql);
if (!$result) {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
// While a row of data exists, put that row in $row as an associative array
// Note: If you're expecting just one row, no need to use a loop
// Note: If you put extract($row); inside the following loop, you'll
// then create $userid, $fullname, and $userstatus
while ($row = mysql_fetch_assoc($result)) {
echo $row["userid"];
echo $row["fullname"];
echo $row["userstatus"];
}
mysql_free_result($result);
Yes, both those should work fine. What's the actual problem you're seeing?
If, as you say, only one record is being returned, try:
select item_name from items order by item_id
and check the full output to ensure you have entries for 001, 012, 103 and 500.
If both those queries only return one row, I would suspect not.
If they all do exist, check the table definitions, it may be that the column is CHAR(4) and contains spaces for the others. You may have genuinely found a bug in MySQL but I doubt it.
After EDIT:
This is a perl/mysql problem, not an SQL one: mysql_fetch_array() returns only one row of the dataset at a time and advances a pointer to the next.
You need to do something like:
$query = "SELECT item_name from items WHERE item_id IN('s001','a012')";
$result = mysql_query($query, $conn) or die (mysql_error());
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
while ($row = mysql_fetch_assoc($result)) {
echo $row["item_name"];
}
Your ID field must be set to auto increment, i guess. i had problems with that once and i changed the auto increment to int. in the IN field if you pass the parameters to match against the auto increment variable you get back only the first parameter, the remaining generates an error.
Use mysql_fetch_assoc to get the query and assign the values from mysql_fetch_assoc query into a an array. Simple as that
$i=0;
$fullArray = array();
$query = mysql_query("SELECT name FROM users WHERE id='111' OR id='112' OR id='113' ")or die(mysql_error());
while($row = mysql_fetch_assoc($query)){
foreach ($row as $value) {
$fullArray[$i] = $value;
}
$i++;
}
var_dump($fullArray);
echo $fullArray[0]."<br/>".$fullArray[1]."<br/>".$fullArray[2];`
You could also use the mysql_num_rows function to tell you how many rows your query retrieved and then use that result to increment a for loop. An example.
$num_rows=mysql_num_rows($query_results);
for ($i=0; $i <$num_rows ; $i++) {
$query_array[]=mysql_fetch_assoc($query_results);
}