count total unique words contained in a field of a resultset - php

how can I count single words appearing in a field of a resultset?
example
id| myfield
1 | pear apple peach watermelon
2 | lime grapes pear watermelon
I want to get 6 because there are 6 unique words
I don't need a fast query, it is just a statistic calculation that will be executed rarely
thanks!

function uniqueWords ($result, $field) {
$words = array();
while ($row = mysql_fetch_assoc($result)) { /* or something else if you use PDO/mysqli/some ORM */
$tmpWords = preg_split('/[\s,]+/', $row[$field]);
foreach ($tmpWords as $tmpWord) {
if (!in_array($tmpWord, $words))
$words[] = $tmpWord;
}
}
return count($words);
}

You can split the results on a space and then add them to an array, such as
foreach($results as $result)
{
$words = explode(" ", $result['myfield']);
$array = array();
foreach($words as $word)
$array[$word] = true;
}
echo count($array);
Probably a better way, but this is quick and dirty

I cannot think of a pure SQL solution - MySQL dosen't really like to split a single row nto many.
A PHP version is easy though:
$sql="CREATE TEMPORARY TABLE words (word VARCHAR(100) PRIMARY KEY)";
//run this according to your DB access framework
$sql="SELECT myfield FROM mytable";
//run this according to your DB access framework
while (true) {
//fetch a row into $row according to your DB access framework
if (!$row) break;
$words=preg_split('/[\s,]+/',$row['myfield']);
foreach ($words as $word) {
//Escape $word according to your DB access framework or use a prepared query
$sql="INSERT IGNORE INTO words VALUES('$word')";
//run this according to your DB access framework
}
}
$sql="SELECT count(*) AS wordcount FROM words";
//run this according to your DB access framework, the result is what you want
$sql="DROP TABLE words";
//run this according to your DB access framework

Related

Combing queries and arraying results

Okay essentially what I'm trying to achieve is to combine the first query with the second one the trouble I'm having is that I'm unable to array out the results from the first query to then use in the second one. Here is my first query what this achieves is that it selects all the room subjects from my users which typically look like this, welcome to my #room hope you #enjoy once is selects one it will then strip the subject of the words and will only keep the hash-tags for example it will keep #room and #enjoy once its goes through and selects all the hash-tags from all of the room subjects it will then order them from how frequent they are used among subjects of all users.
$sql = mysql_query("SELECT subject FROM `users`");
$row = mysql_fetch_array($sql);
$freqDist = [];
foreach($results as $row)
{
$words = explode(" ", $row);
foreach($words as $w)
{
if (array_key_exists($w, $freqDist))
$freqDist[$w]++;
else
$freqDist[$w] = 1;
}
}
arsort($freqDist);
foreach($freqDist as $word => $count)
{
if (strpos($word, '#') !== FALSE)
echo "$word: $count\n";
else
echo "$word: does not contain hashtag, DROPPED\n";
}
Now what I'm trying to achieve here is that I'm trying to array out the results from the above query so then I can perform an action on each hash-tag which is grabbed from above. Below I have included the code and essentially the problem I face lies solely on this line $all = array("hashtag1", "hashtag2", "hashtag3"); as what I'm trying to achieve is instead of typing in directly the hash-tags I want to perform the action on I would want them to be grabbed via using the above query.
$all = array("hashtag1", "hashtag2", "hashtag3");
$trending = $all;
foreach($trending as $tags)
{
$sql = mysql_query("SELECT * FROM `users` WHERE `subject` LIKE '%$tags%'");
$sums = mysql_query("SELECT SUM(viewers) AS viewers FROM `users` WHERE `subject` LIKE '%$tags%'");
$num_rows = mysql_num_rows($sql);
$row = mysql_fetch_assoc($sql);
$sum = mysql_fetch_assoc($sums);
}
So again just to outline my problem I'm trying to grab the results from the first query and use them as an array with the second query. I apologise for the length of this question I just assumed it would help you better understand my question.
As per my understanding, you want to store the hashtag value in an array. if so then just update your foreach()
$hashWord = array();
foreach($freqDist as $word => $count)
{
if (strpos($word, '#') !== FALSE)
echo "$word: $count\n";
$hashWord[] = $word;
else
echo "$word: does not contain hashtag, DROPPED\n";
}

How to generate breadcrumbs using recursion on database row data?

I have to make a breadcrumb menu which comes database.
So made this function
function file_list($path) {
$result = array();
$q = "SELECT staticTitle,staticId,parentId FROM tbl_static_pages WHERE staticId = $path";
$run = mysql_query($q);
while($row = mysql_fetch_array($run)) {
if($row['parentId'] > 1) {
echo $row['staticTitle'];
$result = file_list($row['parentId']);
return $result; // INSERTED
}else {
return $result;
}
}
I have a database structure like this:
id | parentId | title
3 | 1 | keyword
28 | 3 | xxx
31 | 28 | business
I want to output like this business -> xxx -> keyword
I want to run this function until $row['parentId'] = 1.When I echo the title, I got correct result.When I try it to store it in array, I always get single value.
How can I return an array in recursive array?
I REALLY don't like the idea of recursive calls on the database. If this is a "breadcrumbs" database table, how big could it possibly be? ...I mean size is probably not a concern.
I would like to suggest that you pull the full table out (3 columns, all rows) and assign the resultset to a php variable. This means you only ever make one trip to the database -- and that's a good thing.
Code: (Demo)
function breadcrumber($array,$id){
static $result=[]; // declare the storage variable without losing elements during recursion
if(isset($array[$id])){ // if target exists
$result[]=$array[$id]['title']; // store title text
$parent=$array[$id]['parentId']; // assign new target
unset($array[$id]); // remove possibility of an infinite loop
breadcrumber($array,$parent); // recurse
}
return $result;
}
$resultset=[
['id'=>3,'parentId'=>1,'title'=>'keyword'],
['id'=>28,'parentId'=>3,'title'=>'xxx'],
['id'=>31,'parentId'=>28,'title'=>'business']
];
echo implode(' -> ',breadcrumber(array_column($resultset,NULL,'id'),31));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-assign associative keys for easy lookup
Output:
business -> xxx -> keyword
...and here is another demo using your second set of data
Try this:
function file_list($path)
{
$result = array();
$q = "SELECT staticTitle,staticId,parentId FROM tbl_static_pages WHERE staticId = $path";
$run = mysql_query($q);
$results = array();
while ($row = mysql_fetch_array($run))
{
if ($row['parentId'] > 1)
{
echo $row['staticTitle'];
$results = array_merge($results, file_list($row['parentId']));
}
else
{
$results[] = $result;
}
}
return $results;
}
Few things that are not clear from your question:
Breadcrumbs are usually not recursive, so I suppose you do NOT want to actually return a recursive array (array where every element is again array). If you want, follow comment by #midhunjose
Do you expect the query to ever return multiple records?
Swap the order of array_merge arguments, if you want the parent before child in resulting array.
Try this:
$result[] = file_list($row['parentId']);
instand of
$result = file_list($row['parentId']);

Limiting post sql results

Im building a search engine from scratch.
It scans many different tables in multiple databases.
It searches through only the specified columns.
The search words are explode()'ed case of multiple words search
It iterates with a foreach through the tables.
I'm having trouble structuring the code base with LIMIT. I want it to show only DISTINCT.
For example if I search Joe Schmoe my code will search for first = joe and then for last = schmoe, and it will display a result for each search. But I want it to display only one result for the two searches.
<?php
echo "<h1>Search Results</h1>";
echo "<table style='width: 100%;'>";
$a = $_GET["q"];
$b = explode(" ", $a);
include 'db_connect3.php';
mysql_select_db("db440035579", $con);
foreach($b as $c){
$sql="SELECT * FROM users WHERE first LIKE '%$c%' || last LIKE '%$c%'";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo "<a href='applications.php?act=search&uid=$row[7]'>$row[5], $row[4]</a>";
}
}
mysql_close($con);
?>
First of all http://bobby-tables.com/
Secondly, plugging in PDO takes only a few lines of code.
Thirdly, FULL TEXT SEARCH is much better.
And finally:
Use a array microcaching. I assume $row[0] is the user.id. That way you only get one item per ID
$cache = array();
foreach($b as $c){
$sql="SELECT * FROM users WHERE first LIKE '%$c%' || last LIKE '%$c%'";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)){
$cache[$row[0]] = $row;
}
}
foreach($cache as $row){
echo "<a href='applications.php?act=search&uid=$row[7]'>$row[5], $row[4]</a>";
}

php & mysql - loop through columns of a single row and passing values into array

I have a mysql table with columns id, f1, f2, f3, ..., f20 where id is productID and f1,...f20 are product features. Depending on each product, some might have all, none or only some columns filled.
Each column holds a delimited string like a#b#c#d where a,b,c,d are values in different languages (a=english, b=french etc)
I need to select a row by it's id, explode each column's value (f1,f2...) with '#' in order to get the language part I need and then pass the values to an array in order to use in my product spec page.
How do I loop through the fetched row (i'm using $row = my_fetch_array) and put the exploded value into a one dimension array like $specs=('green', 'M', '100', 'kids'...) etc?
PS:I know, is complicated but I cant come up with a better idea right now.
Try this:
$result = mysql_query("...");
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
$arr = array();
foreach ($row as $k=>$v)
{
$features = explode("#", $v);
$value = $features[1]; // get the specific language feature
$arr[] = $value;
}
$specs = join(", " , $arr);
}
Not sure this is the best way togo but you could define an array with your langs, then access the result by lang
<?php
$langs=array('eng'=>0,'fr'=>1,'ger'=>2,'geek'=>3);
while ($row=mysql_fetch_assoc($result)) {
$specs=explode('#',$row['f1']);
$other=explode('#',$row['f2']);
...
}
//Get lang from cookie that you could set elsewhere
$lang=(isset($_COOKIE['lang']))?$_COOKIE['lang']:'eng';
echo $specs[$langs[$lang]];
?>
My solution for how I understand you question:
// Make a MySQL Connection
$sQuery = "SELECT f1,f2,... FROM table WHERE id = ...";
$oResult = mysql_query($sQuery) or die(mysql_error());
//Fetch assoc to use the column names.
$aRow = mysql_fetch_assoc($oResult);
//Prepare the product properties array
$aProductProperties = array("English"=>array(),"French"=>array(),"Dutch"=>array());
//Loop over all the columns in the row
foreach($aRow as $sColName=>$sColVal){
//Explde the column value
$aExplodedCol = explode("#",$sColVal);
//The code below could be nicer when turned into a looped that looped over every language,
//But that would make the code less readable
$aProductProperties['English'][$sColName] = $aExplodedCol[0];
$aProductProperties['French'][$sColName] = $aExplodedCol[1];
$aProductProperties['Dutch'][$sColName] = $aExplodedCol[2];
}
//Done, you should now have an array with all the product properties in every language

i was wondering how to handle a MySQL request in php as an Object?

I was wondering how I can handle a mysql request in php precisely as an object.
Ex:
//supposing...
$beginning=$_GET['start'];//value equal to 3
$ending=$_GET['end'];//value equal to 17
$conn=new mysqli("localhost","user","password","databasename");
$query=$conn->query("select name, favoriteFood, weight, from tablename");
1- Supposing that tablename has 23 rows, how to printing only 14 rows, beginning for example by 3rd row and ending in 17th row, as following?
Ex:
//supposing... It, I guess, should result in error but is a sketch of my ideia
for($i=$beginning,$colsCol=$query->fetch_array(MYSQLI_ASSOC); $i<$ending; $i++)
printf("%s %s %s<\br>",$colsCol['name'][$i],$colsCol['favoriteFood'][$i],$colsCol['weight'][$i]);
2 - And later, how to order the resulted rows with $query variable?
P.S.: I know that to get results ordered, I could user order by columname, but in this case I would like to order the resulted rows after query been done.
If you want to sort later, after the query's done, then you'd need to store the results in a PHP data structure and do the sorting there. Or re-run the query with new sorting options.
As for fetching only certain rows, it'd be far more efficient to retrieve only the rows you want. Otherwise (for large result sets) you're forcing a lot of data to be pulled off disk, sent over the wire, etc... only to get thrown away. Rather wasteful.
However, if you insist on doing things this way:
$row = 0; $data = array();
while($row = $query->fetch_array(MYSQLI_ASSOC)) {
$row++;
if (($row < 3) || ($row > 17)) {
continue;
}
$data[] = $row;
}
for 2D array you can use it.
function asort2d($records, $field, $reverse=false) {
// Sort an array of arrays with text keys, like a 2d array from a table query:
$hash = array();
foreach($records as $key => $record) {
$hash[$record[$field].$key] = $record;
}
($reverse)? krsort($hash) : ksort($hash);
$records = array();
foreach($hash as $record) {
$records []= $record;
}
return $records;
} // end function asort2d
Use SQL for SQL-tasks:
"how to printing only 14 rows, begging for example by 3rd row and ending in 17th row"
$stmt = $database->prepare('SELECT `name`, `favoriteFood`, `weight` FROM `tablename` LIMIT :from, :count');
$stmt->bindValue(':from', (int)$_GET['start'] - 1);
$stmt->bindValue(':count', (int)$_GET['end'] - (int)$_GET['start']);

Categories