My situation:
I have a table ('players') that contains data about players. It has fields: name, surname, lv points, itf points and total points (auto-generated, lv points + itfpoints) and gender. The same table contains data about male and female.
What I want to do is to create a column or select temporary column "Rank" that will be based on total points.
Example:
| rank (temp_col) | name | totalpoints
| 1 | Nick | 199
| 2 | Rob | 190
| 3 | Alex | 155
| 4 | Max | 144
And then I want to get a data for a particular name, like
SELECT rank FROM players WHERE name = 'Nick'
I have separate page for each player and I want to show rank for each person.
My PHP code:
<?php
$sql = "SELECT *, (lvpoints + itfpoints) AS totalpoints FROM players WHERE club = 'TENNISJOY' ORDER BY gender DESC, totalpoints DESC";
$result = mysqli_query($conn, $sql);
$i = 0;
while($row = mysqli_fetch_assoc($result)){
$i += 1;
$name = $row['name'];
$surname = $row['surname'];
$gender = $row['gender'];
$sql2 = "SELECT *, (lvpoints + itfpoints) AS totalpoints FROM players WHERE gender = '$gender' AND name='$name' AND surname='$surname' ORDER BY totalpoints DESC";
$result2 = mysqli_query($conn, $sql2);
$row2 = mysqli_fetch_assoc($result2);
$points = $row2['totalpoints'];
$sql3 = "SELECT
(#cnt := #cnt + 1) AS rank,
surname, name, (lvpoints + itfpoints) AS totalpoints, lvpoints, itfpoints, club
FROM players
JOIN (SELECT #cnt := 0) AS dummy
WHERE gender='$gender'";
$result3 = mysqli_query($conn, $sql3);
$row3 = mysqli_fetch_assoc($result3);
$rank = $row3['rank'];
echo '
<div class="row">
<div class="col-md-4">
<div class="well dash-box">
<h4> ' . $i . '. ' . $surname . ' ' . $name. ' ('. $gender . ') '. '</h4>
<img src="img/noava.png" height="200px" width="200px" />
</div>
</a>
</div>
<div class="col-md-8">
<div class="well dash-box">
<h4 align="left">Player details</h4>
<p align="left">LV Rank : ' . $rank . '<br/><br/>
Total points : ' . $points .'<br/>
LV points : ' . $row['lvpoints'] . '<br/>
<br/>
ITF Rank : <br/>
ITF Points : ' . $row['itfpoints'] . '<br/>
</p>
</div>
</a>
</div>
</div>
';
}
?>
If you have any ideas how to implement it, give a shout, please!
Personally, I would do away with calculating rank on the fly. Instead you would want to calculate this and store it in the table, after modifying the data.
This will require way more code then I care to post right now, but the basic Idea is that when something changes. Say a player gets more "points" you would recalculate the rank for each player, then store that either in the same table, or in a separate but related one.
That way when it comes time to do the query, your data is all there and it's a trivial task to do.
The issue with how you are doing it now, is the data doesn't get saved and therefor you can't query against it later.
The only way to do it on the fly like this would be to filter through the result set of the first ( second ) query that creates that value. This would be prohibitive performance wise, because you would be pulling all players out and then sifting through them for the one you want using PHP.
It's better to front load the performance cost of doing calculations by recalculating this when the data in the table changes, and having a simple numeric value to work with.
Related
I'm making a ranking list based on user earned,
I made the top 10 ranking when it was displayed
but i need to show the ranking from the user but he doesn't have the top 10 ranking
example:
rank1: Jhon
rank2: Jhon 2
rank3: Jhon 3
rank4: Jhon 4
rank5: Jhon 5
rank6: Jhon 6
rank7: Jhon 7
rank8: Jhon 8
rank9: Jhon 9
rank10: Jhon 10
rank465: Jhon 465 (based on user login)
I need Jhon 465 and his rank displayed in the ranking list
here the php sql code
i use smarty framework to show myphp
/** PHP SQL CODE **/
$q = $db->query("SELECT user_id,earned," . $query24h . ", " . $query7d . ", " . $query30d . " FROM bonusads_stats ORDER BY " . $orderby . " DESC LIMIT 10");
while ($r = $db->fetch_array($q)) {
$r['username'] = $db->fetchOne("SELECT username FROM members WHERE id=" . $r['user_id']);
$r['country'] = $db->fetchOne("SELECT country FROM members WHERE id=" . $r['user_id']);
$r['type'] = $db->fetchOne("SELECT type FROM members WHERE id=" . $r['user_id']);
$flag = $bacontest_flags[$r['country']];
$r['country'] = strtolower($flag);
$r['type'] = $membership_name[$r['type']];
$top10[] = $r;
$r['earned'] = $db->fetchOne("SELECT earned FROM bonusads_stats");
}
/** SHOW PHP CODE (USE SMARTY) **/
{foreach from=$top10 item=foo key=k}
<tr style="text-align:center">
<td><span class="rc-position">{$k+1}</span></td>
<td>{$foo.type}</td>
<td> <img src="images/forum/flags/{$foo.country}.png" style="margin-right : 8px" title="{$item.member.country}" />{$foo.username}</td>
<td>{$foo.last24hours}</td>
<td>${$foo.earned}</td>
<td>${$foo.earned * 10}</td>
</tr>
{/foreach}
how to display the ranking of users login but he is not in the top 10 ranks
The best solution is to have two queries, one for the top 10 and one for user score.
For example, make a class Score. Which one will have two methods.
One for the top 10 and one for a single user score.
Let's say both methods return arrays. So then you just need to marge arrays and print out them.
Just add the desire user at the end. If user is already on the top 10. UNION ALL remove the duplicated. You include user_id to avoid cases where two user had same name.
SELECT user_id, user
FROM YourTable
ORDER BY orderField
LIMIT 10
UNION ALL
SELECT user_id, user
FROM YourTable
WHERE user_id = #user_id
i have this code that makes a sum of 2 tables
<div align="right"> Total Vanzari ziua curenta: <i><strong>
<?php
$query = "SELECT (SELECT SUM(totaldeplata) FROM vanzari WHERE
datainregistrarii >= CURRENT_DATE()) + (SELECT SUM(totaldeplata) FROM
players WHERE datainregistrarii >= CURRENT_DATE()) as result";
$query_run = mysql_query($query);
$row = mysql_fetch_assoc($query_run);
$sum = $row['result'];
echo "sum of two different column from two tables : "+ $sum;
?></strong> </i> Lei
</div>
it display a sum of 2 row from 2 different tables
is there a way to store this maximul value into database (its actually the daily sale so the maximum value need to be stored into a table row)
I have two tables and i want to echo the total call count once each user logins:
Login
Firstname | Lastname | Login ID
------------------------------
Tyler | Durden | 3
Call Count
Name | Call Count | Open | GrandTotal
------------------------------
Tyler Durden| 100 | 33 | 133
i tried:
<?php
$result = mysqli_query($mysqli, "SELECT * FROM csvdata WHERE Name=".$_SESSION['firstname']. ' ' .$_SESSION['lastname']." ");
while($res = mysqli_fetch_array( $result )) {
echo $res['Open'].' Open Calls';
echo $res['GrandTotal'].' Grand Total Calls';
}
mysqli_close($mysqli);
?>
But its not working, i think i have to join the the two tables to get it to work. What do you think?
Assuming your Call Count table is actually called csvdata, you'll want to format your SQL request string a bit by adding single quotes around the WHERE name = part.
<?php
$result = mysqli_query($mysqli, "SELECT * FROM csvdata WHERE Name='".$_SESSION['firstname']. ' ' .$_SESSION['lastname']."' ");
while($res = mysqli_fetch_array( $result )) {
echo $res['Call Count'].' Call Count';
echo $res['Open'].' Open Calls';
echo $res['GrandTotal'].' Grand Total Calls';
}
mysqli_close($mysqli);
?>
Good practice would require that you use primary keys to facilitate joins between tables and make sure two users with the same name can be differenciated.
In that case you may want to consider replacing the Name column in your Call Count table for your loginID. This way you could get your name from the Login table (as shown below). Also, as bad as it is to have duplicated data like your user's name in both tables, you do not need your GrandTotal column since you can easily get the sum of CallCount and Open to get the exact same number. In the end, your query should look more like this (assuming your tables are called Login and CallCount).
<?php
$result = mysqli_query($mysqli, "SELECT l.FirstName, l.LastName, cc.CallCount, cc.Open, (cc.CallCount + cc.Open) AS GrandTotal FROM Login AS l JOIN CallCount AS cc ON l.LoginID = cc.LoginID WHERE l.FirstName LIKE \"".$_SESSION['firstname']."\" AND l.LastName LIKE \"".$_SESSION['lastname']."\"");
// ...
?>
Is it possible to SELECT with multiple Array tables. I know it sounds confusing but here is what I have done :
First of all, I've created a form, that has two checkboxes option as follows :
<form action="something.php" method="post">
<input type="checkbox" name="store[]" value="M1">
<input type="checkbox" name="store[]" value="M2">
<input type="submit" value="Go">
</form>
Now after submitting the form, I can view which store selected by doing foreach loop:
$allstore = $_POST['store'];
foreach ($allstore as $store=>$value) {
echo $value;
}
Everything till now works as needed !
However those two values in checkboxes are considered to be table names ! Now how can I find a way to let PHP select either one or two tables based on user selection $value ?
$query = "SELECT * from **{$allstore[0]},{$allstore[1]}** WHERE .....";
As you can see {$allstore[0]},{$allstore[1]} should be created based under foreach loop. I can't seem to find a way of doing it! Can I insert a function to do it for me?
Like this : $query = "SELECT * from ((( Function Here ))) WHERE .....";
If you have a different way of doing it, Please share it.
Edit :
M1 Table
id |item_no |qty |price
1 x1 10 20
2 x2 5 22
3 x3 3 5
M2 Table
id |item_no |qty |price
1 x1 11 20
2 x9 5 30
3 x10 6 26
The output table should be
item_no | price | M1 | M2
x1 20 10 11
x2 22 5 N/A
x3 5 3 N/A
x9 30 N/A 5
x10 26 N/A 6
That's what I am aiming for. I hope it can be solved !
here's the structure for 2 tables sqlfiddle
I think you can add more tables from here.
SELECT T1.item_no,
COALESCE(M1.price,M2.price) as price,
M1.qty as M1,
M2.qty as M2
FROM
(SELECT item_no FROM M1
UNION
SELECT item_no FROM M2
)T1
LEFT JOIN M1 ON T1.item_no = M1.item_no
LEFT JOIN M2 ON T1.item_no = M2.item_no
UPDATED: I am not too familiar with PHP but I looked up some syntax and was able to dynamically generate SQL based on array of either ["M1","M2"] or ["M1"] or ["M2"]
DynamicPHPtobuildSQL
<?php
//Enter your code here, enjoy!
$allstore = ["M2"];
$item = 0;
$sqlpart1 = "";
$sqlpart2 = "";
$sqlpart3 = "";
$sqlpart4 = "";
foreach ($allstore as $store=>$value) {
$item += 1;
if ($item > 1){
$sqlpart1 .= ",";
$sqlpart2 .= ",";
$sqlpart3 .= " UNION ";
}
$sqlpart1 .= $value . ".price ";
$sqlpart2 .= $value . ".qty as " . $value . " ";
$sqlpart3 .= "SELECT item_no FROM " . $value . " ";
$sqlpart4 .= "LEFT JOIN " . $value . " ON T1.item_no=" . $value . ".item_no ";
}
$SQL = "SELECT T1.item_no,COALESCE(" . $sqlpart1 . ") as price," . $sqlpart2;
$SQL .= "FROM (" . $sqlpart3 . ")T1 " . $sqlpart4;
echo $SQL;
?>
Be careful to avoid the risk of SQL injection: compare the posted values against a closed list of existing store table names and reject any other value.
Note also that not only the FROM clause is influenced by the user's choices, but also the SELECT clause. So you have two dynamic parts in your SQL statement.
You could use this code which makes use of array_intersect, implode and array_map:
$selected_stores = $_POST['store'];
// Protect against SQL-injection by only accepting known tables:
$all_stores = array("M1", "M2", "M3");
$selected_stores = array_intersect($selected_stores, $all_stores);
// Build dynamic part of the FROM clause
$from = implode("
UNION
", array_map(function ($store) {
return "SELECT '$store' as store, item_no, price, qty FROM $store";
}, $selected_stores));
// Build dynamic part of the SELECT clause
$cols = implode(",
", array_map(function ($store) {
return "CASE store WHEN '$store' THEN qty END AS $store";
}, $selected_stores));
$sql = "
SELECT item_no,
MAX(price) as price,
$cols
FROM ( $from ) data
GROUP BY item_no
";
The SQL generated looks like this:
SELECT item_no,
MAX(price) as price,
CASE store WHEN 'M1' THEN qty END AS M1,
CASE store WHEN 'M2' THEN qty END AS M2
FROM ( SELECT 'M1' as store, item_no, price, qty FROM M1
UNION
SELECT 'M2' as store, item_no, price, qty FROM M2 ) data
GROUP BY item_no
See also this SQL fiddle.
As a side comment: I would advise to combine all store tables into one table, which would have an additional column indicating the store. This is more in line with normalised database design and will give more advantages than disadvantages in terms of searching, sorting, performance, and simplicity.
I am currently using three different queries to output information from a db.. I've put a sample of what I'm doing below, I'm just curious if there is a more efficient simpler way of spitting out this same info.
I have a db table for events, that has a date field, and parent event field. I have to group the events by their date, spit out the events per each date, then spit out each sub-event underneath those events (by using the parent event field).
Below is a sample of how my code it layed out, I'm just not that good in mysql if there is an easier query etc.
Thanks
$result = mysql_query("SELECT * FROM events GROUP BY date");
while ($event_date = mysql_fetch_assoc($result)) {
echo 'Date Header';
$result2 = mysql_query("SELECT * FROM events WHERE date = '" . $event_date['date'] . "' && parent_id = ''");
while ($event = mysql_fetch_assoc($result2)) {
echo 'Event display code';
$result3 = mysql_query("SELECT * FROM events WHERE date = '" . $event_date['date'] . "' && parent_id = '" . $event['id'] . "'");
while ($event = mysql_fetch_assoc($result3)) {
echo 'Sub Event code';
}
}
}
To achieve a markup like the below.
<h3>Date 1</h3>
<div class="top-level-event">
Some code
</div>
<div class="sub-level-event">
some sub level code
</div>
<div class="sub-level-event">
some sub level code
</div>
<h3>Date 2</h3>
<div class="top-level-event">
Some code
</div>
<div class="sub-level-event">
some sub level code
</div>
<div class="sub-level-event">
some sub level code
</div>
You can use one query:
SELECT * FROM events e1
LEFT JOIN events e2 ON e1.id=e2.parent_id AND e1.date=e2.date
WHERE e1.parent_id=''
ORDER BY e1.date