Hello i have a sql statement that ranks my records and inserts the ranks into a database.
The problem i am having is that when i run the script. It deletes the old rankings. And inserts the new rankings fine, but it inserts every ranking twice. So there will be 2 rank 1's, 2 rank 2's, ect ect.
The kicker to my problem, is if i delete all the records in phpmyadmin. Then run the script. It doesnt make duplicates.
I tried just letting the script delete, to debug if the delete script is working, and it deleted all the rows fine. Hence im really confused :(
if you could look at my code and give me some insight that'd be awesome. Thank you
<?php
// Connect to the database we want to insert/update
$Server_Location = "localhost";
$Server_User_Name = "x";
$Server_Password = "y";
$Database_Name = "z";
// Create connection
$Conn_Info = mysqli_connect($Server_Location, $Server_User_Name, $Server_Password, $Database_Name);
// Check connection
if ($Conn_Info->connect_error) {
die("Connection failed: " . $Conn_Info->connect_error);
}
if($_GET['Password'] != 'q'){
die();
}
$Sql_Delete_Duplicate = "DELETE FROM ranks";
if ($Conn_Info->query($Sql_Delete_Duplicate) === TRUE) {
echo "User Deleted";
}
else {
echo "Error User Not Deleted";
echo $Conn_Info->error;
}
// Overall Games - Rankings (1000)
$Top_1000_Sql = "Select games, overall_games_user.ID as UserID, Name FROM overall_games, overall_games_user WHERE overall_games.User_ID = overall_games_user.ID AND DATE(Date_Updated) = DATE(NOW()) GROUP BY User_ID ORDER BY Games DESC LIMIT 10000";
$Top_1000_Results = $Conn_Info->query($Top_1000_Sql);
$rank = 0;
if ($Top_1000_Results->num_rows > 0) {
echo $Top_1000_Results->num_rows;
while($Top_Player = $Top_1000_Results->fetch_assoc()) {
$rank += 1;
$User_ID = $Top_Player["UserID"];
$Games_Played = $Top_Player["games"];
$Insert_Top_Player_Sql = "INSERT INTO ranks (Rank_Type,Rank, User_ID, games)
VALUES ('Total', {$rank}, {$User_ID}, {$Games_Played})";
if ($Conn_Info->query($Insert_Top_Player_Sql) === TRUE) {
echo $rank . "-";
}
else {
echo "Error User Not Added";
echo $Conn_Info->error;
}
}
}
// Yesterday Games - Rankings
// Graph Stats
/*
SELECT AVG(Games) FROM overall_games WHERE DATE(Date_Updated) = DATE(NOW()) AND User_ID IN (SELECT ID FROM overall_games_user WHERE division LIKE('%BRONZE%'));
SELECT AVG(Games) FROM overall_games WHERE DATE(Date_Updated) = DATE(NOW()) AND User_ID IN (SELECT ID FROM overall_games_user WHERE division LIKE('%SILVER%'));
SELECT AVG(Games) FROM overall_games WHERE DATE(Date_Updated) = DATE(NOW()) AND User_ID IN (SELECT ID FROM overall_games_user WHERE division LIKE('%GOLD%'));
SELECT AVG(Games) FROM overall_games WHERE DATE(Date_Updated) = DATE(NOW()) AND User_ID IN (SELECT ID FROM overall_games_user WHERE division LIKE('%PLATINUM%'));
SELECT AVG(Games) FROM overall_games WHERE DATE(Date_Updated) = DATE(NOW()) AND User_ID IN (SELECT ID FROM overall_games_user WHERE division LIKE('%DIAMOND%'));
*/
?>
You are using Group By without aggregate function so change your query to:
$Top_1000_Sql = "Select Count(games) as gameCount, overall_games_user.ID as UserID, Name FROM overall_games, overall_games_user WHERE overall_games.User_ID = overall_games_user.ID AND DATE(Date_Updated) = DATE(NOW()) GROUP BY UserID ORDER BY Games DESC LIMIT 10000";
Also note change in GROUP BY UserID in above SQL
In $Games_Played variable fetch value of count:
$Games_Played = $Top_Player["gameCount"];
Try Changing VALUES to VALUE in your query.
Also it sometimes so happens that you have an .htaccess to point every thing to the index file. Naturally the browser will request the script twice, once for the script it self, the other is for the favicon.
The fix is to Try to edit the .htaccess to prevent redirection to the index file when the browser is requesting for favicon.ico
Try these two things. I hope it would solve your problem :) Else let me know again.
Related
I have two different tables, one named users, and another named transactions. Transactions contains wallet1, wallet2, amount. Users contains user details such as firstname, lastname, and wallet. I am trying to display the corresponding first name and last name, depending on whether or not the SESSION_wallet is equal to wallet1 or wallet2 within transactions. I tried searching for a while, and came up with a solution for showing the correct display name for the first and last name making the transfer, however, I am trying to make it display the correct value for "Transfer to:"
Here is some of my code to get a better understanding of what I mean:
MySQLi Query:
$result2 = mysqli_query($link, "SELECT * FROM transactions INNER JOIN users ON transactions.wallet1 = users.wallet WHERE transactions.wallet1 = '" . $_SESSION["wallet"] . "' OR transactions.wallet2 = '" . $_SESSION["wallet"] . "' Order by transactions.id DESC LIMIT 5 ");
PHP Code:
<?php
if(mysqli_num_rows($result2) > 0)
{
while($row = mysqli_fetch_array($result2))
{
?>
The table that needs to display the transfer from, and transfer to:
<?php
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["firstname"]." ".$row["lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["firstname"]." ".$row["lastname"]."</td>";
}
?>
Right now my tables are only showing the first and last name of the user that made the Transfer, however, I need it to display the first and last name of the user that the transaction is made to as well. The else if code is working correct, but the first part is not showing the corresponding value.
You will need to JOIN your transactions table to your users table twice, once to get each users name. Then to avoid duplicate column names overwriting the results in the output array, you will need to use column aliases. Something like this should work:
$result2 = mysqli_query($link, "SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = '{$_SESSION["wallet"]}'
OR t.wallet2 = '{$_SESSION["wallet"]}'
ORDER BY t.id DESC
LIMIT 5 ");
Then you can access each user's names as $row['w1_firstname'] etc.:
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["w2_firstname"]." ".$row["w2_lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["w1_firstname"]." ".$row["w1_lastname"]."</td>";
}
Note that ideally you should use a prepared query for this, for example:
$stmt = $link->prepare("SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = ?
OR t.wallet2 = ?
ORDER BY t.id DESC
LIMIT 5");
$stmt->bind_param('ss', $_SESSION["wallet"], $_SESSION["wallet"]);
$stmt->execute();
$result2 = $stmt->get_result();
Hello guys actually i am trying to maintain user logs with ip, last login time and last logout time of users, working in php and mysql. successfully stored ip and login time while user logs in but while updating logout time at the time of logout it updated all logout time for the same user id and i want to update only last logout time of the user id whether he logged in any no of times. can any one help me for the same.
my code is -
if (isset($_SESSION['userId']) && !empty($_SESSION['userId'])) {
include "connection.php";
$userId = $_SESSION['userId'];
$sqluserlogs = "UPDATE userlogs SET LastLogout = now()
WHERE uid = '$userId' ORDER BY uid DESC LIMIT 1";
if (mysql_query($sqluserlogs, $conn)) {
//echo 'success';
} else {
//echo 'failed';
}
}
updated query -
$sqluserlogs = "UPDATE userlogs SET LastLogout = now() WHERE
uid = '$userId' ORDER BY ulogID DESC LIMIT 1";
Thanks in advance
Try a join:
"UPDATE userlogs AS UpdateTable
INNER JOIN (
SELECT JoinTable.id
FROM userlogs AS JoinTable
WHERE JoinTable.uid = '$userId'
ORDER BY uid DESC
LIMIT 1)
AS source ON source.id = UpdateTable.id
SET LastLogout = now()";
I've a table that has three columns id, points, rank. Timely I update data for all fields so points go up and down but old rankings remains same, so I'm trying to find out a way that entitles each id its deserving rank based on points earned.
I've got more than 2000 rows in this table. I wish to do it in php5+ with mysqli? I think I've a solution but it times out even with 1200 seconds timeout setting and memory gets exhausted.
I think my solution works accurately but any of the loops needs some doctor. Here my rough target is 'update' query to go accurate that takes all points in desc order, and awards id a rank against the points earned:
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/includes/db.inc.php';
$a2= mysqli_query($link, "SELECT COUNT(*) as count FROM p1");
$b2 =mysqli_fetch_array($a2);
$count = $b2['count'];
$i=1;
while($i<=$count){
$a1= mysqli_query($link, "SELECT points FROM p1 ORDER BY points DESC LIMIT $i");
if(!$a1){
echo mysqli_error($link);
}
while($po = mysqli_fetch_array($a1)){
$ross[] = $po;
}
foreach($ross as $pot){
$points=$pot['points'];
}
$a5a= mysqli_query($link, "SELECT id FROM p1 WHERE points = '$points'");
while($popo = mysqli_fetch_array($a5a)){
$idi=$popo;
}
foreach($idi as $idm){
$id=$idm['id'];
$rank = $i;
$update = mysqli_query($link,"UPDATE p1 SET rank = '$rank' WHERE points = '$points' AND id ='$id'");
}
if(!$update){
echo "Error updating Rank".mysqli_error($link);
} else {
echo "Succuessul for where id = '$id' and points = '$points' set rank = '$rank'<br/>";
}
$i++;
}
?>
I have replaced my original answer with much leaner and shorter code, you can of course include modification to the rank counter if consecutive users have same points but you can figure this yourself
This code have just one loop and is conserving memory and your DB as well
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/includes/db.inc.php';
$a = mysqli_query($link, "SELECT id, points, rank FROM p1 ORDER BY points DESC "); // lets get users in new ordering
$rank = 1; // new ranks
while($line = mysqli_fetch_array($a)){
if ($rank != $line["rank"]) { //if old rank is different we will hit db with new value
echo "updating id ".$line["id"]." from rank ".$line["rank"]." to rank ".$rank." <br>";
if(!mysqli_query($link,"UPDATE p1 SET rank = '".mysqli_real_escape_string($link,$rank)."' WHERE id ='".mysqli_real_escape_string($link,$line["id"])."'")) {
echo "Error updating Rank".mysqli_error($link);
}
}else { //if its the same we just leave the message for now
echo "ignoring id ".$line["id"]." previous rank ".$line["rank"]." , new rank ".$rank." <br>";
}
$rank++; // next user so lets increment the counter
}
?>
Recently went through same kind of issue and found a simple solution like below after struggling a lot. I would like to clear it out that, it depends on your input and expected result as well which you didn't mention in your post.
if (preg_match('/"'.<value>.'"/i' , json_encode(<your array>))) {
echo "Match";
} else {
echo "Doesn't match";
}
Please replace values accordingly when trying! Thanks for reading it.
The following answer code takes all points, and relevant ids and sets high to low ranks against high to low points respectively. However, it does not assign same rank for same points holder id as it keeps rolling with Rank+1 until end. That could be done, but isn't presently required.
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/includes/db.inc.php'; //connection to the DB
$a1= mysqli_query($link, "SELECT id, points FROM p1 ORDER BY points DESC"); //Selecting High to low all points
if(!$a1){
echo mysqli_error($link);
}
while($po = mysqli_fetch_array($a1)) {
$rose[] = $po;
}
$rank=0;//set rank 0
foreach($rose as $ro) { //splitting each row of array with unlimited rows
$points=$ro['points'];
$id=$ro['id'];
$rank++; //adding 1 each time foreach loops repeats itself until no row left
$update = mysqli_query($link,"UPDATE player1 SET rank = '$rank' WHERE points = '$points' AND id ='$id'"); //sending update command
if(!$update) { //echoing out what the hell this code is f******
echo "Error updating Rank".mysqli_error($link);
} else {
echo "Succuessul for where id = '$id' and points = '$points' set rank = '$rank'<br/>";
}
}
?>
I have 2 table's:
Users (id, username, email, avatar, etc...);
Friends (id, user1, user2, status);
Now I want to build on my profile page an list of my friends with there avatar(s). I'm trying for like 4 hours by myself but i don't get it... :(
BTW: this is an error i got!
Notice: Array to string conversion in /home/reduaqi158/domains/reduankurtaj.eu/public_html/snapfriends/vrienden.php on line 26
This is what i have right now:
<?php
error_reporting(E_ALL);
session_start();
$username = $_SESSION['username'];
$status = 2;
include "includes/conn.php";
$vrienden=mysqli_query($server,"SELECT * FROM vrienden WHERE status='$status' && vriend1='$username' || vriend2='$username' ");
$vriend_list = array();
while($row = mysqli_fetch_array($vrienden))
{
if ($row['vriend1'] == $username) {
$vriend_list[] = $row['vriend2'];
}
else {
$vriend_list[] = $row['vriend1'];
}
}
echo json_encode($vriend_list);
$foto=mysqli_query($server,"SELECT prof_pic FROM users WHERE username='$vriend_list['vriend1''vriend2']' ");
while($row2 = mysqli_fetch_array($foto)) {
echo "<img class='img-rounded' src=assets/profiel/".$row2['prof_pic']." alt='Card image cap'>";
}
?>
json_encode output:
["ja","amando"]
Someone who can help me pls :)
Your initial approach is very confusing.
Almost everything in your code can be substituted by single SQL query.
You can use JOIN to get all your friends with their avatars in one go:
SELECT u.username as username, u.avatar as avatar,.... <== all columns which you need
FROM `friends_table` f <== your friends table
JOIN `users_table` u <== your users table
ON (f.user1 = u.id) <== notice that i join on user1 column
WHERE u.username = '$username' && f.status = '$status'
UNION
SELECT u.username as username, u.avatar as avatar,.... <== same columns
FROM `friends_table` f <== your friends table
JOIN `users_table` u <== your users table
ON (f.user2 = u.id) <== notice that i join on user2 column
WHERE u.username = '$username' && f.status = '$status'
By this query you select all users who are in a friendship with your $username. You need union because you don't know in which field (user1 or user2) your $username is located.
NOTE: I strongly suggest using prepared statements instead of just putting '$var' inside SQL query to prevent SQL Injection.
After executing this query you can parse results and display avatars in such a way:
while($row = mysqli_fetch_array($vrienden, MYSQLI_ASSOC))
{
echo "<img class='img-rounded' src=assets/profiel/".$row['avatar']." alt='Card image cap'>";
}
I hope you got the idea.
in your while statement you have to declare a value for the array. like array[0] = value. so that you know that array position 0 has a certain value. Like what I did here below. Don't know if it's in PHP like this but certain in .net you have to declare the location of a value in an array.
while($row = mysqli_fetch_array($vrienden))
{
if ($row['vriend1'] == $username) {
$vriend_list[0] = $row['vriend2'];
}
else {
$vriend_list[1] = $row['vriend1'];
}
}
and the following
$foto=mysqli_query($server,"SELECT prof_pic FROM users WHERE username='$vriend_list['vriend1''vriend2']' ");
shouldn't it be $vriend_list['vriend1'] . $vriend_list['vriend2']'
you have to use a connect character (the . in PHP)
I recently created a scoring system where the users are ordered by their points on descending basis. First I used to store ranks in a column of its own. I used to run this loop to update the rank:
$i = 1;
$numberOfRows = mysql_query('SELECT COUNT(`id`) FROM sector0_players');
$scoreboardquery = mysql_query("SELECT * FROM sector0_players ORDER BY points DESC");
while(($row = mysql_fetch_assoc($scoreboardquery)) || $i<=$numberOfRows){
$scoreid = $row['id'];
$mysql_qeury = mysql_query("UPDATE sector0_players SET scoreboard_rank = '$i' WHERE id = '$scoreid'");
$i++;
}
And it was really hard, not to mention slow to actually run this on a huge amount of users.
Instead, I tried to construct a query and ended up with this.
SET #rownum := 0;
SELECT scoreboard_rank, id, points
FROM (
SELECT #rownum := #rownum + 1 AS scoreboard_rank, id, points FROM sector0_players ORDER BY points DESC
)
as result WHERE id = '1';
But, this is just a select statement. Is there anyway I could get around it and change it so that it updates the table just as the loop does?
Please try using the following query :
set #rownum:=0;
update sector0_players set scoreboard_rank=#rownum:=#rownum+1 ORDER BY points DESC;
PHP code can be ,
mysql_query("set #rownum:=0;");
mysql_query("update sector0_players set scoreboard_rank=#rownum:=#rownum+1 ORDER BY points DESC;");
You can try using the RANK function .. I haven't actually executed the SQL, but it should work
UPDATE sector0_players
SET scoreboard_rank =
(
SELECT srank
FROM
(
SELECT id,points, RANK() OVER (ORDER BY points) AS srank
FROM sector0_players T
) D
WHERE D.id = sector0_players.id
AND D.points = sector0_players.points
)