I'm making a basic notification system for a practice project. I have several tables, two of which look something like the following:
> Table 1: "Users"
>
userid | username | Firstname | Lastname
1 | Daffy | Daffy | Duck
2 | Flinstone | Fred | Flinstone
3 | dduck | Donald | Duck
>
> Table 2: "Notifications"
>
Notification_id | from_user_id | to_user_id | SeenOrUnseen | type
1 | 1 | 2 | 1 | fRequest
> 2 | 1 | 2 | 0 | comment
> 3 | 1 | 2 | 1 | comment
> 4 | 3 | 1 | 1 | fRequest
> 5 | 2 | 3 | 1 | fRequest
> 6 | 2 | 3 | 0 | comment
> 7 | 3 | 2 | 0 | comment
I then need data from both these tables, and would normally JOIN the tables on the user_id and from_user_id before sending of an sql query. However, a join seems to return multiple values because in the second table there are multiple instances of from_user_id. Instead, i'm querying the database, returning the data in a while loop, and within that while loop sending out another query to the database for a different tables' information:
include('../../db_login.php');
$con = mysqli_connect("$host", "$username", "$password", "$db_name");
$tbl_name = "Profile";
$tplname = "profile_template.php";
$tplname2 = "public_profile_template.php";
$myid = $_SESSION['identification'];
//CHECK CONNECTION
if(mysqli_connect_errno($con)) {
echo "failed to connect" . mysql_connect_error();
}else {
$result = mysqli_query($con, "SELECT * FROM Notifications WHERE to_user_id='$myid'");
$count = mysqli_num_rows($result);
if($count == 0){
$style = "display:none;";
} else {
echo "<ul class='notifications'>";
while($row = mysqli_fetch_array($result)){
$from_user_id = $row['from_user_id'];
$to_user_id = $row['to_user_id'];
$seen = $row['seen'];
$nature = $row['nature'];
$result2 = mysqli_query($con, "SELECT * FROM users WHERE id='$from_user_id'");
$count2 = mysqli_num_rows($result2);
if($count2 != 0){
while($row2 = mysqli_fetch_array($result2)){
$fromFirstname = $row2['Firstname'];
$fromLastname = $row2['Lastname'];
}
if($nature == 'fRequest'){
echo "<li> You have received a friend request from" . $fromFirstname . " " . $fromLastname . "</li>";
}
}
}
echo "</ul>";
}
mysqli_close($con);
}
echo "<div id='NoNotification'></div>";
echo "<div id='Notification' style='" . $style . "'></div>";
?>
Is there a better way of doing this?
Thanks for any help!
You can do something like this:
SELECT n.*, u.*
FROM Notifications n
JOIN users u ON n.from_user_id=u.id
WHERE n.to_user_id=$myid
ORDER BY n.id, u.id
You will get all the data you need. The notification data and the user data. It is better to define which fields you want to retrieve in stead of * so you got a better view of what your using and your not sending data which you don't use.
Als you are using an integer (id) as a string, you can just put the $myid there. Also beaware this is not a safe query for MySQL injection. For more info.
Related
Column title has a lot of duplicated values, more than once.
I need to update the column so, for example if 'gold' is duplicated - it becomes 'gold 1', 'gold 2', etc.
Something like this:
$st = $db->query("select id, title from arts order by title asc");
$st->execute();
$x = 0;
while($row = $st->fetch()){
$title = $row['title'];
//if($title.is duplicated){
$x++;
$title .= ' ' . $x;
$stb = $db->query("update arts set title = '" . $title . "' where id = " . $row['id']);
$stb->execute();
}
}
Any help?
It would be more efficient to do this in pure SQL rather than using PHP. Here is an approach that uses window functions, available in MySQL 8.0.
You can use a subquery to count how many title duplicates exists for each record, and assign a rank to each record within groups of records having the same title. Then, you can JOIN the subquery with the table to update. Where more than one record exists, you can append the row number to every record in the group.
Query:
UPDATE arts a
INNER JOIN (
SELECT
id,
title,
COUNT(*) OVER(PARTITION BY title) cnt,
ROW_NUMBER() OVER(PARTITION BY title ORDER BY id) rn
FROM arts
) b ON a.id = b.id
SET a.title = CONCAT(a.title, b.rn)
WHERE cnt > 1;
Demo on DB Fiddle
Sample data:
| id | title |
| --- | ------ |
| 10 | silver |
| 20 | gold |
| 30 | gold |
| 40 | bronze |
| 50 | gold |
| 60 | bronze |
Results after running the update query:
| id | title |
| --- | ------- |
| 10 | silver |
| 20 | gold1 |
| 30 | gold2 |
| 40 | bronze1 |
| 50 | gold3 |
| 60 | bronze2 |
Please see below code that working for me
// Create connection
$conn = new mysqli($servername, $username, $password,$dbname);
// get all row
$sql = "select id, title from arts order by title asc";
$result = $conn->query($sql);
while ($row=$result->fetch_assoc()) {
$title=$row['title'];
// select where title is same
$sql = "select * from arts where title='".$title."'";
$result2 = $conn->query($sql);
// if number of row is greater then one
if ($result2->num_rows > 1){
$x=0;
while ($row2=$result2->fetch_assoc()) {
$id=$row2['id'];
// skip first row
if($x>0){
$newTitle=$title.' '.$x;
$uquery = "update arts set title='".$newTitle."' where title='".$title."' and id=$id";
$update = $conn->query($uquery);
}
$x++;
}
}
}
and after query run
This works in MySql 5.7:
update arts a inner join (
select * from (
select t.id,
(
select count(*) + 1 from arts
where id < t.id and title = t.title
) counter
from arts t
) t
) t on t.id = a.id
set a.title = concat(a.title, ' ', t.counter)
where a.title in (
select h.title from (
select title from arts
group by title
having count(*) > 1
) h
);
See the demo.
For data:
| id | title |
| --- | -------- |
| 1 | silver |
| 2 | gold |
| 3 | diamond |
| 4 | bronze |
| 5 | gold |
| 6 | bronze |
| 7 | gold |
the result is
| id | title |
| --- | -------- |
| 1 | silver |
| 2 | gold 1 |
| 3 | diamond |
| 4 | bronze 1 |
| 5 | gold 2 |
| 6 | bronze 2 |
| 7 | gold 3 |
I think It would be more efficient to do this in SQL too, but you may can do a function to validate the duplicate, something like this:
function isDuplicated( $title, $db ){
$dp = $db->query("SELECT * FROM arts WHERE title = $title");
if ( $dp->num_rows > 1)
return true;
return false;
}
$st = $db->query("select id, title from arts order by title asc");
$st->execute();
$x = 0;
while($row = $st->fetch()){
$title = $row['title'];
if( isDuplicated( $title, $db ) ){
$x++;
$title .= ' ' . $x;
$stb = $db->query("update arts set title = '" . $title . "' where id = " . $row['id']);
$stb->execute();
}
}
I have two tables, one is comments, and another is likesordislikes
comments
+----+--------+---------------+---------+
| id | userid | usercom | comname |
+----+--------+---------------+---------+
| 35 | 5 | check comment | 12 |
| 36 | 6 | comment test | 12 |
| 37 | 6 | third comment | 12 |
| 38 | 5 | number four | 12 |
| 39 | 7 | fifth | 13 |
| 40 | 4 | 6th | 13 |
| 41 | 18 | seven | 13 |
+----+--------+---------------+---------+
likesordislikes
+----+-------+------+-------+
| id | vtype | uid | comid |
+----+-------+------+-------+
| 1 | 0 | 5 | 35 |
| 2 | 1 | 6 | 35 |
| 3 | 1 | 7 | 35 |
| 4 | 0 | 8 | 36 |
| 5 | 1 | 5 | 36 |
| 6 | 1 | 9 | 35 |
| 7 | 1 | 10 | 36 |
| 8 | 1 | 11 | 36 |
| 9 | 1 | 20 | 35 |
| 10 | 0 | 9 | 35 |
| 11 | 1 | 21 | 37 |
+----+-------+------+-------+
In comments table userid is session id (logged in user) and comname is the post unique id on which comments are made by logged in users.
In likesordislikes table vtype is vote type where (0 = dislike , 1 = like), uid is logged in user id who likes or dislikes a comment and comid is from comments table (id) column
Now, i want to show total number of likes or dislikes under each comment for this specific comment.
the PHP code i am trying is here
$query1 = "SELECT
comments.id,
comments.usercom,
COUNT(likesordislikes.id) AS count
FROM
comments
LEFT JOIN likesordislikes ON
comments.id=likesordislikes.comid
WHERE likesordislikes.vtype='1'
GROUP BY
comments.id";
$query2 = "SELECT
comments.id,
comments.usercom,
COUNT(likesordislikes.id) AS count
FROM
comments
LEFT JOIN likesordislikes ON
comments.id=likesordislikes.comid
WHERE likesordislikes.vtype='0'
GROUP BY
comments.id";
$stmt = $DB->prepare($query1);
$stmt->execute();
$likes = $stmt->fetchAll();
$tlikes = count($likes);
$stmt = $DB->prepare($query2);
$stmt->execute();
$dislikes = $stmt->fetchAll();
$tdislikes = count($dislikes);
$slt = "SELECT * FROM `comments` where `comname` = '$c_name' and `post` = '$type'";
$res = mysqli_query($con, $slt);
while($fetch = mysqli_fetch_array($res)) {
echo $fetch['usercom']."<br />";
echo "Likes ".$tlikes."<br />";
echo "Dislikes ".$tdislikes;
}
that way, its not showing each comments likes/dislikes under that comment
in more clearer way, I want this result
Comments:
check comment
Likes 4 - Dislikes 2
comment test
Likes 3 - Dislikes 1
third comment
Likes 1 - Dislikes 0
number four
Likes - Dislikes
fifth
Likes - Dislikes
6th
Likes - Dislikes
seven
Likes - Dislikes
But its showing Likes 4 - Dislikes 2 on each comment on the article 12
Can anyone please check whats wrong in it?
You're basically getting all the likes and dislikes, for all the comments:
$query1 = "...";
$query2 = "...";
// ...
$tlikes = count($likes);
// ...
$tdislikes = count($dislikes);
And printing them for all the comments:
echo $fetch['usercom']."<br />";
echo "Likes ".$tlikes."<br />";
echo "Dislikes ".$tdislikes;
Which is why you're getting the same values for every comment. In order to fix your current code, you could create a map for $likes and $dislikes, like this:
$stmt = $DB->prepare($query1);
$stmt->execute();
$likes = array();
while($like = $stmt->fetch(PDO::FETCH_ASSOC){
$likes[$like['id']] = $like['count'];
}
And then, change your printing to something like:
while($fetch = mysqli_fetch_array($res)) {
echo $fetch['usercom']."<br />";
echo "Likes ".(empty($likes[$fetch['id']])?0:$likes[$fetch['id']])."<br />";
// ...
}
Note: You probably should filter the likes and dislikes queries the same way you filter the comments query (so you don't ask for things you won't use)
An alternative way is changing your three queries for a single one, which would change your code to something like this:
$slt =
"SELECT" .
" c.usercom," .
" SUM(CASE WHEN lod.vtype=1 THEN 1 ELSE 0 END) likes," .
" SUM(CASE WHEN lod.vtype=0 THEN 1 ELSE 0 END) dislikes" .
" FROM" .
" comments c LEFT JOIN likesordislikes lod ON lod.comid=c.id" .
" WHERE" .
" c.comname = '$c_name' AND c.post = '$type'" .
" GROUP BY" .
" c.id"
;
$res = mysqli_query($con, $slt);
while($fetch = mysqli_fetch_array($res)) {
echo $fetch['usercom']."<br />";
echo "Likes ".$fetch['likes']."<br />";
echo "Dislikes ".$fetch['dislikes'];
}
Here you have the query in case you want to see it working
Update
If you don't want to show two zeros, you could change your while to something like:
while($fetch = mysqli_fetch_array($res)) {
echo $fetch['usercom']."<br />";
if($fetch['likes']==='0' && $fetch['dislikes']==='0'){
$fetch['likes'] = '';
$fetch['dislikes'] = '';
}
echo "Likes ".$fetch['likes']."<br />";
echo "Dislikes ".$fetch['dislikes'];
}
Your query looks at the comname columns meaning it would give you everything for article 12 as you call it summed up and not separate for each of them.
You should be looking at the ids - something like
$slt = "SELECT * FROM `comments` where `id` = '$id' and `post` = '$type'";
where $id is the id in your comments table.
I am not sure how you can get this given the code you have shown but give it a try.
I have a table named users with a column called user_subs. It looks like this.
In user_subs I have stored the specific users session username. Lets say this specific users name is James.
Now how would I loop through a specific user_subs looking for "James" and remove him from that specific user_subs without removing all the other names.
This is what I have so far and the only problem is, its deleting all the usernames in user_subs instead of just "James".
if(isset($_GET['p_id'])) {
$the_post_id = $_GET['p_id'];
$the_post_author = $_GET['author'];
}
if(isset($_POST['delete_sub'])) {
$username = $_SESSION['username'];
$query = "SELECT user_subs FROM users WHERE username = '{$username}' ";
$select_users_by_id = mysqli_query($connection, $query);
while ($row = mysqli_fetch_array($select_users_by_id)) {
$user_subs = explode(',', $row['user_subs']);
foreach($user_subs as $out) {
$query = "UPDATE users SET user_subs = null WHERE username = '{$the_post_author}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
}
}
THIS IS JUST IN TEST, PREPARED STATEMENTS WILL BE USED BEFORE GOING LIVE
Thank you for your time.
I second the other user's comment about moving this column to a different table. In the meanwhile, if you want to achieve what you are asking for, you can try removing the user name from the column value and update it with the remaining text.
if(isset($_POST['delete_sub'])) {
$username = $_SESSION['username'];
$query = "SELECT user_subs FROM users WHERE username = '{$username}' ";
$select_users_by_id = mysqli_query($connection, $query);
while ($row = mysqli_fetch_array($select_users_by_id)) {
$user_subs = str_replace($username . ',', '', $row['user_subs']);
$query = "UPDATE users SET user_subs = '{$user_subs}' WHERE username = '{$the_post_author}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
}
OPTION-2
$user_subs = explode(',', $row['user_subs']);
$user_subs_new = [];
foreach($user_subs as $out) {
if ($out !== $username) {
$user_subs_new[] = $out;
}
}
$user_subs = implode(',',user_subs_new);
$query = "UPDATE users SET user_subs = '{$user_subs}' WHERE username = '{$username}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
Let's start over. Let's start here, in fact...
DROP TABLE IF EXISTS users;
CREATE TABLE users
(user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,email VARCHAR(20) NOT NULL UNIQUE
);
DROP TABLE IF EXISTS user_subs;
CREATE TABLE user_subs
(user_id INT NOT NULL
, sub_id INT NOT NULL
, active TINYINT NOT NULL DEFAULT 1
, PRIMARY KEY(user_id,sub_id)
);
INSERT INTO users VALUES
(1,'b.smyth634#gmail.com'),
(2,'james#gmail.com'),
(3,'f#gmail.com'),
(4,'sally#gmail.com'),
(5,'thomas#gmail.com');
INSERT INTO user_subs (user_id,sub_id) VALUES
(1,5),
(1,2),
(1,1),
(1,4),
(2,1),
(2,2),
(2,4);
SELECT * FROM users;
+---------+----------------------+
| user_id | email |
+---------+----------------------+
| 1 | b.smyth634#gmail.com |
| 2 | james#gmail.com |
| 3 | f#gmail.com |
| 4 | sally#gmail.com |
| 5 | thomas#gmail.com |
+---------+----------------------+
SELECT * FROM user_subs;
+---------+--------+--------+
| user_id | sub_id | active |
+---------+--------+--------+
| 1 | 5 | 1 |
| 1 | 2 | 1 |
| 1 | 1 | 1 |
| 1 | 4 | 1 |
| 2 | 1 | 1 |
| 2 | 2 | 1 |
| 2 | 4 | 1 |
+---------+--------+--------+
SELECT u.*
, GROUP_CONCAT(us.sub_id) subs
FROM users u
JOIN user_subs us
ON us.user_id = u.user_id
GROUP
BY u.user_id;
+---------+----------------------+---------+
| user_id | email | subs |
+---------+----------------------+---------+
| 1 | b.smyth634#gmail.com | 1,2,4,5 |
| 2 | james#gmail.com | 1,2,4 |
+---------+----------------------+---------+
From here we have a choice. We can either DELETE subs we no longer wish to consider, or simply UPDATE them as 'inactive'.
Either way, we just need a DELETE or an UPDATE. So no SELECT needed. In fact a SELECT would, as I mentioned, be counterproductive - because a user may modify the data set in between the execution of the SELECT and the execution of the UPDATE/DELETE. This is known as a 'race condition'.
I want to create summery report from two tables. one table project_type another ffw
Table ffw :
|-----------------------------------------------------------------------|
| ffw_id | division_id | district_id | project_type_id | name
|-----------------------------------------------------------------------|
| 1 | 30 | 1 | 2 |myAddress
|-----------------------------------------------------------------------|
| 2 | 12 | 2 | 1 | Asdfads |
|-----------------------------------------------------------------------|
| 3 | 30 | 6 | 1 | kkkkk |
|-----------------------------------------------------------------------|
| .. | .. | .. | .. | ..... |
|-----------------------------------------------------------------------|
Table project_type:
|--------------------------------
| project_type_id | project_type |
|--------------------------------|
| 1 | food |
|--------------------------------|
| 2 | work |
|--------------------------------|
| 3 | visit |
|--------------------------------|
| .. | .. |
|--------------------------------|
My desired result from that two tables after applying division_id condition will be
|-------------------------------------------|
| no | project_type | count |
|-------------------------------------------|
| 1 | food | 2 |
|-------------------------------------------|
| 2 | work | 1 |
|-------------------------------------------|
| 3 | visit | . |
|-------------------------------------------|
| .. | .. | .. |
|-------------------------------------------|
I am trying this code but it displaying duplicate value in while loop
$qry = "
SELECT * FROM `project_type`
LEFT JOIN `ffw`
ON project_type.project_type_id = ffw.project_type_id
WHERE 1
";
if (strlen($_POST["division_id"]) > 0 && $_POST["division_id"] != "0")
{
$qry .= " AND division_id = '".$_POST["division_id"]."'";
}
$query = mysql_query($qry);
You can use GROUP BY for summarize the result as like that:
SELECT pt.project_type, count(*) as count FROM project_type pt
LEFT JOIN ffw ff ON ff.project_type_id = pt.project_type_id
GROUP BY pt.project_type
This query will return you the summary of your records.
Here is the complete example of your code by using MYSQLi Object Oriented:
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT pt.project_type, count(*) as count FROM project_type pt
LEFT JOIN ffw ff ON ff.project_type_id = pt.project_type_id
WHERE 1 = 1
";
if(strlen($_POST["division_id"])> 0 && $_POST["division_id"]!="0")
{
$sql.= " AND division_id = '".$_POST["division_id"]."'";
}
$sql .= "GROUP BY pt.project_type";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$i = 1;
// output data of each row
while($row = $result->fetch_assoc()) {
echo $id. " - Name: " . $row["project_type"]. " " . $row["count"]. "<br>";
$i++;
}
}
else
{
echo "0 results";
}
$conn->close();
Side Note: I suggest to use mysqli_* OR PDO, because mysql_* is deprecated and its not available in PHP 7
You can use group_by and get count as below :
$qry="SELECT pt.project_type_id as no, pt.project_type, count(*) as count FROM project_type pt LEFT JOIN ffw ON pt.project_type_id=ffw.project_type_id";
if(strlen($_POST["division_id"])>0&&$_POST["division_id"]!="0")
{
$qry.=" Where division_id='".$_POST["division_id"]."'";
}
$qry.=" GROUP BY pt.project_type";
I was suggested to ask this question again but with more depth.
Here is my script:
<?php
//Loggedin
if($_SESSION['login']!=1)
{
print "You must be logged in.";
include($root . 'footer.php');
exit;
}
//Check banned account
elseif($ui['level']=="2"){
print "Sorry but your account is banned.";
include($root . 'footer.php');
exit;
}
//Check email verified
elseif($ui['email_check']=="0"){
print "Sorry but your account has not been verified, to verify your account now please visit <a href='index.php?index=verify&email=".$ui['email']."'>THIS LINK</a>.";
include($root . 'footer.php');
exit;
}
date_default_timezone_set('America/New_York');
$country= $ui['country'];
$dates=mysql_query("SELECT * FROM `contest` WHERE `countries` LIKE '%$country%'");
$timestamp = time();
$getcontests = $os_DB->query("SELECT * FROM contest WHERE date_1 <= '$timestamp' AND date_2 >= '$timestamp' AND countries LIKE '%$country%'");
$num = $os_DB->num($getcontests);
if($num == 0){
print"<td colspan='4'>There are currently no active contests</td>";
}
else
{
while ($dat = mysql_fetch_array($dates)) {
$tname = preg_replace('/\s+/', '', $dat['name']);
$places="(SELECT * FROM `".$tname."_contest` WHERE `username` <> 'cassa' ORDER BY `completed` DESC LIMIT ".$dat['rewards'].")";
$results=mysql_query($places) or die(mysql_error());
$reward = array("".$dat['reward_1'].",".$dat['reward_2'].",".$dat['reward_3'].",".$dat['reward_4'].",".$dat['reward_5'].",".$dat['reward_6'].",".$dat['reward_7'].",".$dat['reward_8'].",".$dat['reward_9'].",".$dat['reward_10']."");
$rewards = implode(",", $reward);
$rewardsa = explode(",", $rewards);
$i=0;
$a=1;
// Offers Contest
if(time() <= $dat['date_2'] && time() >= $dat['date_1'] && $dat['type'] == offer) {
print" <table width ='100%'><tr><th align='center'><font size='4'>{$dat['name']}</font></th><th align='right'><font size='1'>".date("m/d/Y h:i A", $dat['date_1'])."-".date("m/d/Y h:i A", $dat['date_2'])."</font></th></tr></table><br />".$dat['desc']."<br /><font size='1' color='white'>You must complete offers worth at least ".$dat['min_points']." points or $".$dat['min_cash']." to count towards contest!<br /><br />
You must also complete at least ".$dat['min_offers']." offers in order to be eligible for winnings.</font><br /><br />";
print" <table width ='100%'><tr><th align='left'>Place</th><th align='center'>User</th><th align='right'>Prize</th><th align='right'>Completed</th></tr>";
if(mysql_num_rows($results) == 0){
foreach($rewardsa as $rewa){
if(!empty($rewa['$i'])){
if($dat['r_type'] == points){
print" <tr><td align='left'>{$a}</td><td align='center'>......</td><td align='right'>{$rewardsa[$i]} points</td><td align='right'>--</td></tr>";
}
if($dat['r_type'] == cash){
print" <tr><td align='left'>{$a}</td><td align='center'>......</td><td align='right'>$".$rewardsa[$i]."</td><td align='right'>--</td></tr>";
}
$i++;
$a++;
}
}
}
while ($place = mysql_fetch_array($results)) {
if($dat['r_type'] == points){
print" <tr><td align='left'>{$a}</td><td align='center'>{$place['username']}</td><td align='right'>{$rewardsa[$i]} points</td><td align='right'>{$place['completed']}</td></tr>";
}
if($dat['r_type'] == cash){
print" <tr><td align='left'>{$a}</td><td align='center'>{$place['username']}</td><td align='right'>$".$rewardsa[$i]."</td><td align='right'>{$place['completed']}</td></tr>";
}
$i++;
$a++;
}
///Line I am working with///
$getyou= mysql_query("SELECT COUNT(*) AS Place, t.*
FROM ".$tname."_contest t
GROUP BY t.id
HAVING Place <= 3 OR username = '".$ui['username']."'");
$youu = mysql_fetch_array($getyou);
print" <tr><td align='left'>{$youu['Place']}</td><td align='center'>You</td><td align='right'>---</td><td align='right'>{$youu['completed']}</td></tr>";
}
}
}
?>
</table>
With this script I want to be able to show the logged user the place that they currently stand in the contest under the current winners.
This is what I want the table to look like.
-----------------------------------------
| Place | User | Prize | Completed |
| 1 | Someuser1 | $5.00 | 5 |
| 2 | Someuser2 | $2.50 | 3 |
| 3 | Someuser3 | $1.25 | 2 |
| 20 | You | --- | 1 |
-----------------------------------------
This is how it looks
-----------------------------------------
| Place | User | Prize | Completed |
| 1 | Someuser1 | $5.00 | 5 |
| 2 | Someuser2 | $2.50 | 3 |
| 3 | Someuser3 | $1.25 | 2 |
| 1 | You | --- | 1 |
-----------------------------------------
here is my table structure.
Column | Type | Null | Default
--------------------------------------
id |int(11)| No |
username |text | No |
completed|int(11)| No |
As you can see it is all coming from one table and the place isn't defined by the database, but by the script itself.
Hopefully this can clarify more than my last question.
Edit: With Sean's code this is what I get.
-----------------------------------------
| Place | User | Prize | Completed |
| 1 | kikkat | $5.00 | 1 |
| 2 |xXchris744Xx| $2.50 | 1 |
| 3 | kira423 | $1.25 | 1 | /// This line is me
| 7 | You | --- | 1 | /// But it shows my current place as 7
-----------------------------------------
This can be done with a nested query -
$getyou= mysql_query("SELECT
(SELECT count(*)+1 AS rank FROM contest WHERE completed >
(SELECT completed FROM contest WHERE username = '".$ui['username']."' ORDER BY completed DESC LIMIT 1)) as Place,
c.* FROM contest c WHERE username = '".$ui['username']."'");
$youu = mysql_fetch_array($getyou);
print" <tr><td align='left'>{$youu['Place']}</td><td align='center'>You</td><td align='right'>---</td><td align='right'>{$youu['completed']}</td></tr>";
Here is how the query works from the inside out-
The 1st (inside) SELECT gets the completed amount for the username =$ui['username']
SELECT completed FROM contest WHERE username = '".$ui['username']."' ORDER BY completed DESC LIMIT 1
The 2nd (middle) SELECT uses that completed amount and does a count of all the rows that have more completed, adds a 1 to that count, and saves it as the users Place.
SELECT count(*)+1 AS rank FROM contest WHERE completed > '#' // # represents the `completed` amount for the `$ui['username']` that we got in the 1st SELECT
The 3rd/Last (outside) SELECT now just gets the row data for username =$ui['username']
SELECT Place, c.* FROM contest c WHERE username = '".$ui['username']."' // Place was created/defined in early SELECTS, now we just get the rest of the data using c.*
Edit
To add a tiebreaker when one or more have the same number completed, you need to order your query by the id as well. So change your first query to -
$places="(SELECT * FROM `".$tname."_contest` WHERE `username` <> 'cassa' ORDER BY `completed`,`id` DESC LIMIT ".$dat['rewards'].")";
---
And add ORDER BY id and >= to the 2nd query
$getyou= mysql_query("SELECT
(SELECT count(*)+1 AS rank FROM contest WHERE completed >=
--
(SELECT completed FROM contest WHERE username = '".$ui['username']."' ORDER BY completed DESC LIMIT 1) ORDER BY `completed`,`id`) as Place,
-------------------------
c.* FROM contest c WHERE username = '".$ui['username']."'");
Edit #2
Try this new query. The previous one was not selecting the exact row, but the last of the tied.
$getyou= mysql_query("SELECT Place, c.* FROM
(SELECT #Place:=#Place+1 AS Place, c.*
FROM contest c, (SELECT #Place := 0) r ORDER BY completed DESC, id ASC ) c
WHERE username = '".$ui['username']."'");
This new query creates a temporary new column Place, using SELECT #Place := 0, and then we get the users 'Place' using #Place:=#Place+1 AS Place.