PHP/MySql simpler more efficient code - php

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

Related

How would I select and display the most recently added rows from a SQL table?

I am making an extremely basic posting system, and I cant seem to figure out how to get the most recent rows from a certain table. I have tried other solutions offered here, but my posts were randomly placed. How would I accomplish this? My code is below.
function load_posts(){
$posts_sql = "SELECT * FROM posts";
$posts_result = Phoenix\Database\Database::$database->query($posts_sql);
while($row = $posts_result->fetch_assoc()){
$posts_display = '
<div class = "card" style = "width:500px">
<div class = "card-body">
<div class = "card-title">'. $row['username'] .'</div>
<p>'. $row['content'] .'</p>
</div>
</div>
';
echo $posts_display;
}
}
Again, I want the posts to be displayed from most recent, to old.
You need to have information in each row that captures this information. The most common suspects are:
an auto-incrementing id
a creation date
Then you just ask the database to sort the results. For instance, if post_id is an auto-incremented id:
select p.*
from posts p
order by p.post_id;
SELECT * FROM TableName ORDER BY id DESC
// order by should be with primary key

PHP MySQL get data from temporary column

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.

Php grouping select query

So I have persons associated with publications
My current query is this:
$query = "SELECT confAuth.personid, publicationconf.title FROM confAuth INNER JOIN publicationconf ON publicationconf.conferenceid = confAuth.conferenceid GROUP BY publicationconf.conferenceid";
It does group by conference id but only one person id is diplayed for each entry. Obviously, what I need is to display all person id's
Thanks in advance.
As a classmate just noted, this is our print statement and it is probably wrong. Any input to this.
$result = $conn->query($query);
$rows = $result->num_rows;
if ($rows > 0)
{
for($i=0; $i<$rows; $i++)
{
if($row = $result->fetch_assoc())
{
?>
<div class="row">
<div class="col-md-10">
<p><?php echo $row["personid"] . ", " . $row["title"]?></p>
Use group_concat(confAuth.personid) to get a comma delimited list of all values in the grouped set.
However, since you are wanting one line item per personid/title combo, add the personid and the title to the group by clause.
Also, consider table aliases for readability.
$query = "SELECT ca.personid, pc.title
FROM confAuth ca
INNER JOIN publicationconf pc ON pc.conferenceid = ca.conferenceid
GROUP BY pc.conferenceid, ca.personid, pc.title";

retrieve and display php array values when retrieving all records from database

I am displaying the complete record of the user in the My profile section, I am fetching all the rows , but the problem is within the rows I've got two fields as arrays, which are 'secondarySubject' and 'secondaryGrade' now I want the display to be something like this
2002-2004 ----------- A Level ------- School Name
Science A
Maths B
I am able to display them but it prints the dates, school name and level name with every subject rather than just once for all the subjects. I am posting my code, can someone pleaseeee help me with it.
$result2 = $db->query('
SELECT *
FROM secondaryEducation
WHERE userID = "'.$graduateID.'"
ORDER BY secondaryFinishDate DESC
');
$totalRows2 = mysql_num_rows($result2);
if($totalRows2 > 0)
{
$html .= '<h2>Secondary Education: '.$option.'</h2>';
while($row = mysql_fetch_assoc($result2))
{
$startYear = formatDate($row['secondaryStartDate'], 'Y');
$finishYear = formatDate($row['secondaryFinishDate'], 'Y');
if (!empty($row['secondaryGrade']))
$secondaryGrade = getSecondaryGradeName($row['secondaryGrade']);
else
$secondaryGrade = $row['secondaryGradeCustom'];
$html .= '
<div class="secondaryListing">
<div><strong>'.$startYear.' - '.$finishYear.' '.stripslashes($row['secondarySchool']).'</strong></div>
<div>'.stripslashes(getSecondaryLevelName($row['secondaryLevel'])).' in '.stripslashes(getSecondarySubjectName($row['secondarySubject'])).' - '.stripSlashes($secondaryGrade).'</div>
</div><!-- End education listing -->
';
}
}
It looks like those are inside the while statement. Every time it loops it will include it. Try moving it outside the while statement.

While loop displaying result 3 times

Basicly I'm trying to make a simple news feed but I'm stuck at the moment as my while loop display the result 3 times, why is this? :/
<?php
$sql ="SELECT
*
FROM
news,
admins";
$result = mysql_query($sql);
if(!$result)
{
echo 'Error while selecting from database. Please contact the administration team';
} else {
while($row = mysql_fetch_assoc($result))
{
echo '
<div class="content_news">
<h1>' . $row['news_name'] . '</h1>
<p style="font-size:12px;">Posted by <b>' . $row['admin_name'] . '</b> on ' . $row['news_date'] . '
<p>' . $row['news_description'] . '</p>
read more
</div>
';
}
}
?>
If you'd like to see what I am talking about: http://freewallpaperblog.com/freshrp/
Ignore the last 2(those are static html not php)
your query selects data from 2 tables (news, admins) so it joins every row of 1st table with every row of 2nd table
SELECT * FROM news, admins
i recommend you to use following query
SELECT news.*, admins.admin_name FROM news
INNER JOIN admins ON news.admin_id = admins.id
where admin_id is your correct column name
You either have 3 admins or 3 rows of news. Your query makes a direct multiplication between tables. Try "left join" instead...
SELECT * FROM news
INNER JOIN admins ON admins.id = news.adminid
Or whatever adminid is in the news table.
Try the following query:
SELECT
*
FROM
news
Inner join admins on news.admin_id = admins.id
You made no JOIN statement in your SQL, as someone else has already commented on in your question. It would help if you posted the associated fields you're grabbing, but based on your $row keys, my best guess is the following should work for you (but I can't promise it will without knowing how your database is designed, I can only infer from the variable names):
$sql = "SELECT news.name, news.date, news.description, news.link, admins.name"
. "FROM news"
. "INNER JOIN admins"
. "ON news.name=admins.name"
References:
http://www.w3schools.com/sql/sql_join_inner.asp
http://www.w3schools.com/sql/sql_join_left.asp
http://dev.mysql.com/doc/refman/5.0/en/join.html

Categories