Friends of a user + mutual friend test with another user - mysql

I have this table that I use (but not only) for storing friends in a database :
user_1 | user_2 | status
where 'status' can be -1,0 or 1. Here, we will consider only cases where status are '0' (pending for user_1) or '1' (approved by user_2). I have the following query to look for pending/approved friends for a given $user :
SELECT user_1,user_2,status
FROM Friends
WHERE (user_2 = '$user' OR user_1 = '$user') AND status >= 0;
The goal here is to modify the query to also tell if a given $user2 is a common (approved) friend of $user1 and each (approved) friend of $user1.
After some researches, I figured out that the left join would do the trick, by setting another field to either NULL (if no mutual) or $user2. I would want to do it efficiently. I tried several shots, but no success around it.
Thanks by advance for your help
EDIT : For example, let's say we have the following entries :
a | b | 1
c | a | 1
c | b | 1
a | d | 1
I want to list the friends of 'a' and for each friend f of 'a', verify if 'b' is a common friend of f and 'a'. Also, f =/= b for the mutual test. The result of such a query would be :
a | b | 1 | NULL
c | a | 1 | b
a | d | 1 | NULL
Let me know if you need more clarification

As in MySQL query would be so complicated and slow, that I wouldn't use it myself, here's a solution in PHP, with only one query:
<?php
// $db = mysqli_connect(...);
function findMutualFriends($of,$mutual_with){
global $db;
$user_friends = array();
$mutual_friends = array();
$results = array();
$res = mysqli_query($db,"SELECT user_1,user_2,status FROM Friends WHERE ((user_2 = '$of' OR user_1 = '$of') OR (user_2 = '$mutual_with' OR user_1 = '$mutual_with')) AND status >= 0;";
while($row = mysqli_fetch_assoc($res)){
if($row['user_1'] == $of || $row['user_2'] == $of){
$user_friends[] = (($row['user_1'] == $of) ? $row['user_2'] : $row['user_1']);
}
if($row['user_1'] == $mutual_with || $row['user_2'] == $mutual_with){
$mutual_friends[(($row['user_1'] == $mutual_with) ? $row['user_2'] : $row['user_1'])] = 1;
}
}
foreach($user_friends as $friend){
if($mutual_firends[$friend]){
$results[] = $friend;
}
}
return $results;
}
?>
Please notice that it haven't been tested. May contain some minor syntax error, but should return an array of mutual friends.

I modified a bit the Flash Thunder's function post. Just tested with some modifications and it works ! Thanks again.
function findMutualFriends($pdo, $of,$mutual_with){
$user_friends = array();
$mutual_friends = array();
$results = array();
$query = "SELECT user_1,user_2,status FROM Friends WHERE ((user_2 = '$of' OR user_1 = '$of') OR (user_2 = '$mutual_with' OR user_1 = '$mutual_with')) AND status = 1;";
$prep = $pdo->prepare($query);
$res = $prep->execute();
$rows = $prep->fetchAll();
foreach ($rows as $row) {
if($row['user_1'] == $of || $row['user_2'] == $of) {
$user_friends[] = ($row['user_1'] == $of ? $row['user_2'] :$row['user_1']);
}
if($row['user_1'] == $mutual_with || $row['user_2'] == $mutual_with) {
$mutual_friends[($row['user_1'] == $mutual_with ? $row['user_2'] :$row['user_1'])] = true;
}
}
foreach($user_friends as $friend) {
$results[$friend] = $mutual_friends[$friend] == true ? true : false;
}
return $results;
}

Related

Find the depth of a child from a tree menu with mysqli query

MYSQL TABLE
|id|parent_id|
|1 | 0| <- depth 1
|2 | 1| <- depth 2
|3 | 1| <- depth 2
|4 | 2| <- depth 3
|5 | 3| <- depth 3
|6 | 4| <- depth 4
I need to find out the depth of id 4 which in the above case it's 3
Is it possible to do it with one mysqli query?
If not, how can I do that with multiple mysqli queries?
Many many thanks.
EDITED
function find_depth($id, $depth = 0){
global $con;
$query = "SELECT * from table WHERE `id` = $id";
if ($result = $con->query($query)){
if (mysqli_num_rows($result) == 1){
$row = $result->fetch_array();
$depth = $depth + 1;
find_level($row['parent_id'], $depth);
} else {
return $depth;
}
}
}
find_depth('4')
will give me 3
However, I am still looking for a better way to achieve that
If the table is not huge, you can do only one query to DB
function find_depth($id, $depth = 0) {
global $con;
$temp = array();
$query = "SELECT * from table";
if ($result = $con->query($query)) {
while($row = $result->fetch_array())
$temp[$row['id']] = $row['parent_id'];
do { $depth = $depth + 1; } while($id = $temp[$id]);
}
return $depth;
}
find_depth('4');

How to count the date to make a list of events?

I'm using Codeigniter V2.1.3 and I have a calendar template that have a scheduling stuff and I want to count the events in a particular date. Here is my database:
----Table: schedule -----
id | materialID | borrowerID | date_reserve |
------------------------------------------------
1 | 7 | 7 | 2013-08-16 |
2 | 10 | 10 | 2013-08-16 |
1 | 12 | 13 | 2013-08-18 |
What I want is in my calendar template the total event for the date=2013-08-16 will be 2 events. Here is my code which is not working coz it keeps on sending me only 1 event maybe you could figure out where is my mistake in here:
$query = $this->db->select('*')->from('schedule')->like('date_reserve', "$year-$month")->get();
$cal_data = array();
foreach ($query->result() as $row) {
$index = ltrim(substr($row->date_reserve,8,2), '0');
$cal_data[$index] = count($row->borrowerID). 'event(s)';
}
return $cal_data;
Any help?
If you want number of events for exact date: YYYY-MM-DD you can replace like with where:
$r = $this->db->select('id, materialID, borrowerID, date_reserve')
->where('date_reverse', $year."-".$month."-".$day)
->get('schedule')
->result();
Also you can print_r the result so you will see what the result is. Also you can echo last query: echo $this->db->last_query();
Edit:
We had to run query per each date to fetch the number of events.
$cal_data = array();
for($i=1;$i<=31;$i++)
{
$this->db->select('COUNT(id) as count,date_reserve,borrowerID');
$this->db->from('schedule');
$this->db->where('date_reserve',"$year-$month-$i");
//$this->db->group_by('date_reserve');
$query = $this->db->get();
foreach ($query->result() as $row) {
$cal_data[$index] = $row->count. 'event(s)';
}
try using group_by
public function get_results($date) {
$this->db->select('COUNT(id),date_reserve');
$this->db->from('schedule');
$this->db->like('date_reserve',$date);
$this->group_by('date_reserve');
$result = $this->db->get();
return $result->result_array();
}

Propel criteria? or is it even possible to create such query?

I have 3 tables: product, product_parameter, product_parameter_item.
Product and product parameter have no foreign references, product_parameter_item has product_id and product_parameter_id.
For example i have 4 products:
1
2
3
4
Product_parametetrs:
1 - Model
2 - Color
Product_parameter_item:
id - product_id - product_paramter_id - value:
1 - 1 - 1 - Toyota
2 - 1 - 2 - white
3 - 2 - 1 - Toyota
4 - 2 - 2 - black
5 - 3 - 1 - Citroen
6 - 3 - 2 - white
7 - 4 - 1 - Citroen
8 - 4 - 1 - black
How can I get all products with Model = Toyota, Color = Black ?
$c->addJoin(ProductPeer::ID, ProductParameterItemPeer::PRODUCT_ID);
$c->addJoin(ProductParameterItemPeer::PRODUCT_PARAMETER_ID, ProductParameterPeer::ID);
foreach ($product_params as $i => $param){
$c1 = $c->getNewCriterion(ProductParameterPeer::ID, $param->getId());
$c2 = $c->getNewCriterion(ProductParameterItemPeer::VALUE, $value);
$c1->addAnd($c2);
$c->addAnd($c1);
}
Doesnt work
$c->addJoin(ProductPeer::ID, ProductParameterItemPeer::PRODUCT_ID);
foreach ($product_params as $i => $param){
$c1 = $c->getNewCriterion(ProductParameterItemPeer::ID, $param->getId());
$c2 = $c->getNewCriterion(ProductParameterItemPeer::VALUE, $value);
$c1->addAnd($c2);
$c->addAnd($c1);
}
Doesnt work either
$c->addJoin(ProductParameterItemPeer::PRODUCT_PARAMETER_ID, ProductParameterPeer::ID);
foreach ($product_params as $i => $param){
$c->add(ProductParameterPeer::ID, $param->getId());
$c->add(ProductParameterItemPeer::VALUE, $value);
}
I have made this function to get ids of products and add them to Criteria. Didnt find another way :(
$product_params = ProductParameterPeer::getParamsForFilter();
$ids = false;
if (count($product_params)){
$sql = '';
$clause = '';
$clauses = array();
$make_query = false;
foreach ($product_params as $i => $param){
if ($values[$param->getAlias()]){
$is_last = end($product_params) == $param;
$sql .= '(SELECT product_id FROM `product_parameter_item` WHERE `value` = "'.$values[$param->getAlias()].'" AND `product_parameter_id` = '.$param->getId().' ) t'.$i.($is_last?' ':', ');
$clauses[] = 't'.$i.'.product_id';
$make_query = 'SELECT t'.$i.'.product_id FROM ';
}
}
if (count($clauses) == 1) $clause = 'WHERE '.$clauses[0];
else if (count($clauses) == 2) $clause = 'WHERE '.$clauses[0].'='.$clauses[1];
else if (count($clauses) > 2){
$clause = 'WHERE ';
for ($i = 1; $i < count($clauses); $i++){
$clause .= '('.$clauses[0].'='.$clauses[$i].')'.($i == count($clauses)-1 ? '' : ' AND ');
}
}
if ($make_query){
$query = $make_query.$sql.$clause;
$con = Propel::getConnection();
$statement = $con->prepare($query);
$statement->execute();
$ids = array();
while($stmt = $statement->fetch(PDO::FETCH_ASSOC)) {
$ids[] = (int)$stmt['product_id'];
}
}
}
return $ids;

php script to move data between columns with mysql

What I want to achieve is to move the data between 2 rows within one table.
Column A
--------
FN2
1 200x310mm
2 400x260mm[+0.84]
3 500x500mm[+11.34]
Column B
--------
0.0000
0.0000
0.0000
0.0000
This is how it should look like after the data move:
Column A
--------
FN2
1 200x310mm
2 400x260mm
3 500x500mm
Column B
--------
0.0000
0.0000
+0.84
+11.34
What I want is that the query between the [ ] is moved to column B and replaces the 0.0000
How can I achieve this?
Kind Regards
just to illustrate what Yadav said
$query = "SELECT columnID, columnA FROM table";
$result = mysql_query($query,$conn);
while ($row = mysql_fetch_array($result)){
$id = $row['columnID'];
$a = $row['columnA'];
$pos1 = strpos($a,"[")+1;
$pos2 = strpos($a,"]");
$b = substr($a,$pos1,$pos2-$pos1);
$query = "UPDATE table SET columnB = $b WHERE columnID = $id";
mysql_query($query,$conn);
}//end while
edit: Yadav obviously proposed a better answer while I was typing mine...
try this it works for you here i used id as unique key ... and test is my database
<?php
$con=mysql_connect("localhost","root","");
$db=mysql_select_db("test");
$query=mysql_query("SELECT * FROM test where columnA LIKE '%[%]'");
while($row=mysql_fetch_assoc($query))
{
if(preg_match_all('/\[(.*?)\]/',$row['columnA'],$match))
{
mysql_query("UPDATE test SET columnB='".$match[1][0]."' WHERE id=".$row['id']."");
}
}
?>

need an associative array from two mysql colums

i have a mysql table
||==========||==========||==========||
|| id || name || age ||
||==========||==========||==========||
|| 1 || joe || 10 ||
|| 2 || harry || 20 ||
|| 3 || jane || 45 ||
|| 4 || john || 56 ||
|| 5 || larry || 89 ||
|| 6 || henry || 23 ||
|| 7 || steve || 25 ||
|| 8 || eric || 56 ||
|| 9 || dave || 98 ||
|| 10 || mat || 56 ||
||==========||==========||==========||
i need the sql query that would make an associative array from this table and give me values like this
id=>age
1=>10
4=>56
i also need to make all the id's as a variable where there value would be the age like
$1 = 10
$4 = 56
or if i could add a prefix to the variables
$id_1 = 10
$id_4 = 56
thanks in advance
In PHP, mysql_fetch_assoc() takes the result of a query, and returns one row as an associative array. Call it repeatedly to get all rows.
if your using php for fetching your data you may use the function mysql_fetch_array example:
while($row = mysql_fetch_assoc($resource))
{
echo $row['name'].'<br>';
}
you may know more about mysql functions for php on this site: http://www.php.net/manual/en/book.mysql.php
$ids = '1, 4';
$sql = "select age from __TABLE__ where id in ( {$ids} )";
$link = mysql_connect('__SERVER__', '__DBUSER__', '__DB_PWD__') or die('connect error');
$db = mysql_select_db('__DBNAME__', $link) or die('db error');
$rs = mysql_query($sql, $link);
$result = array();
while($row = mysql_fetch_assoc($rs))
{
$result[] = $row;
}
extract(my_result($result));
var_dump($id_1);
var_dump($id_4);
function my_result($result, $prefix = 'id_')
{
$data = array();
foreach($result as $k => $v)
{
$data[$prefix . $v['id']] = $v['order_no'];
}
return $data;
}