Alphabetically ordered list from mysqli join query - php

I am trying to print out an alphabetically ordered list of usernames after using a mysqli join query to select userid's from a friends table.
Friends table consists of
id - userid_one - userid_two - friendship_date - friendship_type
Users table has a pretty standard layout, and the only field I really need from it is the username (to display) and the userid to link the two tables
what i want to achieve is the below
A
Andy
Anna
B
Bobby
Brian
The code i am using is below.
$ir['userid'] //the current users id
$getfriends = mysqli_query($con,"SELECT * FROM friends INNER JOIN users ON (friends.userid_one = users.userid OR friends.userid_two = users.userid) WHERE (userid_one = '{$ir['userid']}' OR userid_two = '{$ir['userid']}') ORDER BY username") or die("query error");
$last="";
if(mysqli_num_rows($getfriends) == 0)
{
print"<li>You have no friends....sorry</li>";
}
else
{
while($gotf=mysqli_fetch_array($getfriends))
{
if($gotf['userid_one'] == $ir['userid']){$friend = $gotf['userid_two'];}else{$friend = $gotf['userid_one'];}
$printed_array = explode(",",$printed);
if(!in_array($friend,$printed_array))
{
$username_of_user = get_username_no_link($friend);
$current_letter = $username_of_user[0];
if ($last != $current_letter) {
print"<li class='Label'>{$current_letter}</li>";
$username_of_user = get_username_nd_avatar($friend);
print"<li>".$username_of_user."</li>";
$last = $current_letter;
$printed = $printed.",".$friend;
}
elseif($last == $current_letter){
$username_of_user = get_username_nd_avatar($friend);
print"<li>".$username_of_user."</li>";
$last = $current_letter;
$printed = $printed.",".$friend;
}
}
}
}
I have not got much experience of using JOIN in mysqli queries and my issue is that I am not getting the list sorted alphabetically as the below example shows.
A
Andy
T
Thomas
S
Sandra
Sally
UPDATE--
the order in which the usernames display, now seems to change randomly after reloading the page, which is further confusing the matter!

question now answered after some playing around. Ended up putting the usernames into an array, then sorting the array alphabetically by value, as well as adding a $printed_array array to add each friend to after they were printed to prevent them being printed out twice.
$usersnames = array();
while($gotf=mysqli_fetch_array($getfriends))
{
if($printed != ""){$comma = ",";}
if($gotf['userid_one'] == $ir['userid']){$friend = $gotf['userid_two'];}else{$friend = $gotf['userid_one'];}
$printed_array = explode(",",$printed);
if(!in_array($friend,$printed_array))
{
$username_of_user = get_username_no_link($friend);
$usersnames[] = $username_of_user;
$printed = $printed.$comma.$friend;
}
}
sort($usersnames);
foreach($usersnames as $name)
{
$getuserid = mysqli_query($con,"SELECT userid,avatar FROM users WHERE username = '$name' LIMIT 1");
$gotuserid = mysqli_fetch_array($getuserid);
//var_dump($gotuserid);
$displaypic = "<img style='height:30px;vertical-align:middle;margin:5px;' src='".$gotuserid['avatar']."'>";
$current_letter = $name[0];
if ($last != $current_letter)
{
print"<li class='Label'>{$current_letter}</li>";
print"<li><a href='profile/".$name."'>".$displaypic.$name."</a></li>";
$last = $current_letter;
}
elseif($last == $current_letter)
{
print"<li><a href='profile/".$name."'>".$displaypic.$name."</a></li>";
$last = $current_letter;
}
}

Related

Pass id's to url on a count being diplayed in table

I have a function in which I am returning a count which when displayed is clickable. When clicked on this count the page redirects to listing of the of users with their details. The count displayed has link to the information page with id's of the users passed in URL. I am not getting the result as the link shows only one user id instead of two(as per database) or some irrelevant id's. Where I am missing the thing, any help will be highly appreciated.
function for displaying count,
function clearedmodule()
{
$id= '';
$res = mysql_query("SELECT id from tbl_users WHERE status= 1 AND type = 3 ");
while($row = mysql_fetch_array($res))
{
$query = mysql_query("SELECT DISTINCT user_id FROM tbl_user_quiz GROUP BY user_id HAVING COUNT(DISTINCT module_id) = '".$this->userQuestionModules()."' AND SUM(cleared) = 0 ");
while($row1 = mysql_fetch_assoc($query))
{
foreach($row1 as $cname => $id)
{
$id .= $row['id'].',';
}
}
}
return substr($id, 0, -1);
}
Now the <td> where the count is being displayed,
<td>Not Cleared</td>
<td>
<?php
$ids = $rep->clearedmodule();
$ids = explode(",",$ids) ;
$linkId = $rep->clearedmodule();
if($linkId)
{ ?>
<?php echo count($ids); ?>
<?php
}
else{
echo "0";
}
?> </a></td>
Using above, the URL I am getting is
reportNotCleared.php?Userid=10131183 where 1013 is right id , 1183 is not at all correct and I want them to be comma separated.
Your second query is the only query you needed. Just remove all the loops except the middle one and you should be good to go!
function clearedmodule() {
$query = mysql_query("SELECT DISTINCT user_id FROM tbl_user_quiz GROUP BY user_id HAVING COUNT(DISTINCT module_id) = '".$this->userQuestionModules()."' AND SUM(cleared) = 0 ");
while($row1 = mysql_fetch_assoc($query)){
$id .= $row1['user_id'] . ',';
}
return substr($id, 0, -1);
}

php mysql search row with multiple arrays in cells

ok, so stay with me here ...
i have a site with a table of about 80,000 rows; i am trying to search this table with one MySQL query. The problem is that each of the fields in the row i'm searching has / might have an array (ex: year = 2017,2016,2015, etc), and some of them may not have anything at all. i have tried doing a loop through to and build my "WHERE" clause as i pull the results, but that isn't working either.
any thoughts? any and all help will be greatly appreciated.
CODE:
INSERT INTO the table - this is one of the 13 different rows
if(!empty($_POST['pd_year']) && is_array($_POST['pd_year'])) {
$pd_year = implode(",", $_POST['pd_year']);
$insert_year = mysqli_query($con, "UPDATE prod_desigs_search_test SET pds_year = '$pd_year' WHERE s_id = '$search'");
} elseif(empty($_POST['pd_year'])) {
$insert_year = mysqli_query($con, "UPDATE prod_desigs_search_test SET pds_year = ' ' WHERE s_id = '$search'");
}
SELECT THE design and check if it is an array or not:
$get_search = mysqli_query($con, "SELECT * FROM prod_desigs_search_test WHERE s_id = '$s_id'");
while($new_search = mysqli_fetch_array($get_search)) {
$pd_year_ex = $new_search['pds_year'];
if(!empty($pd_year_ex) && is_array($pd_year_ex)) {
$pd_year = explode(",", $pd_year_ex, 0);
$year = $pd_year[0];
} elseif(!empty($pd_year_ex) && !is_array($pd_year_ex)) {
$year = $pd_year_ex;
}
$search = mysqli_query($con, "SELECT * FROM prod_designs WHERE pd_year = '$year'");
while($row_search = mysqli_fetch_array($search)) {
EDIT
I have tried to build out the "WHERE" in the query dependent on the is_array check like this:
$where = "WHERE ";
if(!empty($pd_year_ex) && is_array($pd_year_ex)) {
$pd_y = $pd_year[0];
foreach ($pd_y as $year) {
$where .= "pd_year LIKE '%".$year."%'";
}
} elseif(!empty($pd_year_ex) && !is_array($pd_year_ex)) {
$where .= "pd_year LIKE '%".$pd_year_ex."%'";
} elseif(empty($pd_year_ex)) {
$where .= "";
}
and this doesn't seem to be working either. i am just trying to understand how to do a search like this:
$search = mysqli_query($con, "SELECT * FROM designs WHERE pd_year LIKE '%2017,2016,2015%'")(etc)
I know it won't go with the above, but how do i search a table for something like this?

Choosing the correct SQL query based off user input

Lets say the user only entered in an artist to search by, how do I get PHP to recognize that the user is only looking for an artist and should therefore setup a query only for the artist. The way I have currently done it works, but it is very ineffective when the user wants a variety of search options.
$artist = $_POST["artistSearch"];
$topic= $_POST["topicSearch"];
$date = $_POST["dateSearch"];
$title = $_POST["titleSearch"];
$artistLength = strlen($artist);
$topicLength = strlen($topic);
$dateLength = strlen($date);
$titleLength = strlen($title);
if ($artistLength>2 && $topicLength<2 && $dateLength<2 && $titleLength<2) {
$sql=("Select * FROM music WHERE artist = '$artist' ORDER BY date");
}
if ($artistLength>2 && $topicLength>2 && $dateLength<2 && $titleLength<2) {
$sql=("Select * FROM music WHERE artist = '$artist' AND topic = '$topic' ORDER BY date");
}
if ($artistLength>2 && $topicLength>2 && $dateLength>2 && $titleLength<2) {
$sql=("Select * FROM music WHERE artist = '$artist' AND topic = '$topic' AND date = '$date' ORDER BY date");
}
if ($artistLength>2 && $topicLength>2 && $dateLength>2 && $titleLength>2) {
$sql=("Select * FROM music WHERE artist = '$artist' AND topic = '$topic' AND date = '$date' AND title = '$title' ORDER BY date");
}
$result = mysqli_query($con,$sql);
Simple, you build up the query string in stages. Ignoring your sql injection attack vulnerability, and assuming that all options should be ANDed together, you can do something like:
$options = array();
if ($artist) {
$options[] = "artist = '$artist'";
}
if ($topic) {
$options[] = "topic = '$topic'";
}
etc...
$where_clause = implode(' AND ', $options);
$sql = "SELECT ... WHERE $where_clause";

Php - mysql - Return number of rows

I am trying to get the number of friends that a user has, but I can't seem to get it to work, so i'm really hoping that you can help me.
Here is the php
$findFriendssql = "select u.firstName, u.id from friends f, user u
where (f.u_ID1 = '$loggedId' and u.id = f.u_id2)
or (f.u_id2 = '$loggedId' and u.id = f.u_id1)";
$all_friends_sql = $db->getRows($findFriendssql);
//$number_of_friends = mysql_num_rows($all_friends_sql);
if ($all_friends_sql) {
$number_of_friends = mysql_num_rows($all_friends_sql);
$friends = "";
foreach ($all_friends_sql as $one_post) {
//doing stuff here.
and here is the get rows function
public function getRows($sql) {
$result = array();
$table = mysql_query($sql, $this->db_link);
if (!$table) {
die("\"$sql\" seems to be an invalid query: " . mysql_error());
}
while ($row = mysql_fetch_assoc($table)) {
array_push($result, $row);
}
return $result;
}
whatever I try - I get the error that the num rows expects parameter 1 to be resource.
thank you in advance
$findFriendssql = "select u.firstName, u.id from friends f, user u where (f.u_ID1 = '$loggedId' and u.id = f.u_id2)
or (f.u_id2 = '$loggedId' and u.id = f.u_id1)";
$all_friends_sql = $db->getRows($findFriendssql);
//$number_of_friends = mysql_num_rows($all_friends_sql);
if (count($all_friends_sql)>0) {
$number_of_friends = mysqli_num_rows($all_friends_sql);
$friends = "";
foreach ($all_friends_sql as $one_post) {
The num row is supposed to happen immediatelly after this:
$table = mysql_query($sql, $this->db_link);
$totalFirends = mysql_num_rows($table);
Use $table as input parameter. $table is supposed to be a resource. to be able to use mysql_num_rows.
The following in your function changes $table not to be a resource anymore. Besides you do not need this code to know how many friend the user has:
while ($row = mysql_fetch_assoc($table)) {
array_push($result, $row);
}
return $result;
}
Also if you just need the number then the query should change to SELECT COUNT(some-field)
And I do not know what is the content of $loggedId hope you tested that the query returns what is supposed to return. is correct the output of the query with a sample data, let say in phpmyadmin?

How can I optimize this function? I need to loop though users, and then loop through user submitted data, and update values, it's taking > 1 minute

How can I optimize this function? I need to loop though users, and then loop through user submitted data, and update values, it's taking > 1 minute for 264 users with around 80 records per user.
public function calculateUserPoints(){
set_time_limit(0);
/* Select users */
$sql = "SELECT user_id FROM users";
$query = $this->db->prepare($sql);
$query->execute();
$users = $query->fetchAll(PDO::FETCH_ASSOC);
/* User guesses Query */
$ug_sql = "SELECT
guesses.guess_id AS r_guess_id, guesses.user_id, guesses.game_id, guesses.team_1_score AS guess_team_1, guesses.team_2_score AS guess_team_2, guesses.joker,
games.game_id, games.game_team_1, games.game_team_2, games.real_score_team_1, games.real_score_team_2,
users.user_id AS usr_id
FROM games
JOIN users
ON users.user_id = :user_id AND games.real_score_team_1 IS NOT NULL AND games.real_score_team_2 IS NOT NULL
LEFT JOIN guesses
ON guesses.user_id = users.user_id
AND guesses.game_id = games.game_id
";
$ug_query = $this->db->prepare($ug_sql);
foreach($users as $u){ /* Loop users */
/* Get guesses per user basis */
/*echo 'User '.$u['user_id'].'<br/>';*/
$ug_query->bindParam(':user_id', $u['user_id']);
$ug_query->execute();
$usr_guesses = $ug_query->fetchAll(PDO::FETCH_ASSOC);
$u_points = 0;
$sql = "UPDATE users SET points = :u_points WHERE user_id = :usr_id";
$query = $this->db->prepare($sql);
$sql2 = "UPDATE guesses SET guess_points = :guess_points WHERE guesses.guess_id = :guess_id";
$query2 = $this->db->prepare($sql2);
foreach($usr_guesses AS $ug){
$err = false;
$g_points = 0;
if(isset($ug['guess_team_1']) && isset($ug['guess_team_1'])){
$g_points = $this->calcPoints($ug['guess_team_1'], $ug['guess_team_2'], $ug['real_score_team_1'], $ug['real_score_team_2'], $ug['joker']);
} else {
$u_points -= 1;
}
$u_points += $g_points;
/* echo $ug['guess_team_1'].' - '.$ug['guess_team_2'].' :: '.' '.$ug['real_score_team_1'].' - '.$ug['real_score_team_2'].' jk: '.$ug['joker'].' / pt: '.$g_points.':: T: '.$u_points.'<br/>';*/
$query->bindParam(':u_points', $u_points);
$query->bindParam(':usr_id', $u['user_id']);
$query2->bindParam(':guess_points', $g_points);
$query2->bindParam(':guess_id', $ug['r_guess_id']);
if($query->execute() && $query2->execute()){
$err = false;
} else {
$err = true;
}
}
}
if($err == true){
return false;
} else {
return true;
}
}
guess_id and user_id are indexes on all columns.
I'm not looking for a code answer, I'd prefer merely a push in the right direction.
Thanks.
$sql = "SELECT user_id FROM users"; can be joined with $ug_sql query into one query.
If you use InnoDB tables, you can do the updates in transaction, it will speed it up.
And think about removing some indexes, they slow down inserts, updates, and deletes.

Categories