Converting two loops to smarty - php

I have two cycles in PHP, that I needed converting to smarty structure. Down includes PHP code.
Code:
<pre>
$query = mysqli_query($cnn, "SELECT *, COUNT(*) AS ph FROM course INNER JOIN completed_course ON course.id = completed_course.id_course GROUP BY course.id");
while ($row = mysqli_fetch_array($query)){
<tr> <td> <?php echo $row['id']; ?></td><td> <?php echo $row['nazev']; ? </td><td>
?php echo $row['ph']; ? </td> <td>
?php
$Number_of_graduates = mysqli_query($cnn, "SELECT COUNT(*) AS abs FROM participant where id_completed_course = $row[id]");
while ($rAbs = mysqli_fetch_array($Number_of_graduates)){
echo $rAbs['abs'];
} ?
</td>
</pre>
The question is. How to convert the second loop where first id from SQL?

Ok, so your question is really about SQL. Let's look at your queries. The first one looks like this:
SELECT *, COUNT(*) AS ph
FROM course
INNER JOIN completed_course ON course.id = completed_course.id_kurz
GROUP BY course.id
I'm assuming (because I don't know anything about your database scheme) that this is going to give a list of courses and the number of students (maybe - I don't know what's in the completed_course table) who completed them. As written, this query is going to also give you some data from the completed_course table, but it's likely to be meaningless since you're grouping only on course.id.
The second query is:
SELECT COUNT(*) AS abs
FROM participant
WHERE id_completed_course = {DATA FROM FIRST QUERY}
Presumably, this query is intended to give you the total number of participants of completed courses. To make that work, the WHERE clause could look like this:
SELECT COUNT(*) AS abs
FROM participant
WHERE id_completed_course IN (
SELECT course.id FROM
FROM course
INNER JOIN completed_course ON course.id = completed_course.id_kurz
)
Notice that I'm taking the values selected in the first query and making them part of an IN clause. This query can be simplified significantly - for instance, the JOIN in the subquery is really only selected ID values from the completed_course table:
SELECT COUNT(*) AS abs
FROM participant
WHERE id_completed_course IN (
SELECT id_kurz
FROM completed_course
)
And the query will actually be more efficient if you get rid of the subquery altogether and just join the participants to the completed_course table.
SELECT COUNT(*) AS abs
FROM participant
INNER JOIN completed_course ON participant.id_completed_course=completed_course.id_kurz
This last query is going to give you one value: the number of participants whose id_completed_course value corresponds to an item in the completed_course table. You can use the mysqli methods to retrieve this data and pass it to your Smarty template.

Related

PHP Query within a while fetch loop

I was wondering if it was possible to run a query inside a while loop which is used to display the content of a SQL table.
Here is the code if I'm not clear enough :
$sql="SELECT * FROM hotels WHERE rooms>0";
$req=$db->query($sql);
while($row=$req->fetch()){
//The second query to check how many place is left
$req2=$db->query('SELECT COUNT(*) FROM people WHERE idhotels='.$row["idhotels"].';');
echo "hey".$req2;
$left_rooms= $row["rooms"] -$req2;
echo '<option value="'.$row["idhotels"].'">'.$row["name_hotel"].' ('.$left_rooms.' rooms left)</option>';
}
What I'm trying to do here, is to display a list of hotels with the number of rooms left. The problem is I have to count how many rooms are taken before displaying the number of rooms left, hence the second request.
My code obviously doesn't work, but I can't figure out why.
Can someone help me ?
Many thanks !
Why not using a join and a group by so you only have one query ?
$sql="SELECT h.idhotels,h.name_hotel,count(*) FROM hotels h inner join people p on h.idhotels = p.idhotels WHERE h.rooms>0 group by h.idhotels,h.name";
while($row=$req->fetch()){
// Here do whatever you want with each row
}
Have you tried to calculate your left rooms in the database with a joined query like:
SELECT rooms - COUNT(*) AS left_rooms FROM hotels h WHERE rooms > 0 JOIN people p ON (p.idhotels = h.idhotels) GROUP BY h.idhotels, h.name ORDER BY left_rooms ASC;

Distinct Values from MySQLi Query

I am trying to only show unique userIds (userIds are (0,1,2,3,4,5,6,7,8,9 etc...) for the query I am running. I tried using DISTINCT in my query, but it only shows me unique values of the rows that have 2 or more of the same userId.
Is there a way I can use php to only show the unique values. My weak points are arrays and it makes it more complicated because its using data from a MySQLi query.
Example right now I have with the query now (lets say its GROUP BY rentPaid DESC and the rent total is 800.00 for all users):
userID rentPaid rentMonth
2--------800.00------April
1--------500.00------April
3--------400.00------April
3--------400.00------April
1--------200.00------April
1--------100.00------April
Example desired output:
userID rentPaid rentMonth
2--------800.00------April
1--------500.00------April
3--------400.00------April
Can I do this with MYSQL because I tried DISTINCT and it wouldn't work, how about PHP?
Query:
SELECT
properties.*,
leases.*,
users.userId, users.primaryPhone,
CONCAT(users.userFirstName,' ',users.userLastName) AS user,
admins.adminName, payments.*
FROM
properties
LEFT JOIN leases ON properties.propertyId = leases.propertyId
LEFT JOIN assigned ON properties.propertyId = assigned.propertyId
LEFT JOIN admins ON assigned.adminId = admins.adminId
LEFT JOIN users ON properties.propertyId = users.propertyId
LEFT JOIN payments ON properties.propertyId = payments.propertyId
WHERE
payments.rentMonth = '$currentMonth' AND
payments.rentYear = '$currentYear'
Edit: Please excuse my formatting, this is my first post.
Edit: Added query....its long, but works lol. I only want unique userIds (no double or triple userIds etc...)
I suspect this is what you want:
SELECT userID, MAX(rentPaid) AS maxRentPaid, rentMonth
FROM yourTable
WHERE rentMonth = "April"
GROUP BY userID
ORDER BY maxRentPaid

Assistance with MySQL left outer join and differentiating query results from same key

I am trying to learn about SQL joins and trying to apply them to an application I am building. I am doing a query to find a "game record" on a schedule based on a specific game id. But on this game record; for the "h_team" and the "v_team"; only the ids of the teams are on the game record. And so what I want to do is join the "teams" table and look up the two different team_names of the "h_team" and "v_team". I have it also pull in a "division name" as well using a join since only the division id is stored on the game record. I have gotten this all to work fine; except I do not know how to get the results separately for the "team_name" for h_team and v_team. Basically the key for each one is just "team_name"; I will paste in my code and then explain further:
$array_game_id6=32;
$sql = "SELECT * FROM playoff_schedule LEFT OUTER JOIN teams on playoff_schedule.h_team = teams.team_id || playoff_schedule.v_team = teams.team_id LEFT OUTER JOIN playoff_divisions on playoff_schedule.po_div_id = playoff_divisions.po_div_id WHERE tom_game_id=$array_game_id6";
foreach ($dbh->query($sql) as $resultsg39)
{
$h_team=$resultsg39[h_team];
$v_team=$resultsg39[v_team];
$po_div_id=$resultsg39[po_div_id];
$round=$resultsg39[round];
$game_id=$resultsg39[game_id];
$date=$resultsg39[date];
$timestamp=$resultsg39[timestamp];
$h_score=$resultsg39[h_score];
$v_score=$resultsg39[v_score];
$tom_game_id=$resultsg39[tom_game_id];
$h_name=$resultsg39[team_name];
$div_name=$resultsg39[playoff_name];
}
the problem comes in when i am trying to get the results of the query and store them all in the different variables…
the last two "$h_name" and "$div_name" are being pulled from the JOINs all the prior ones are on the game record itself…
what I want to do is store both the names from "v_team" and "h_team" in the respective variables $h_name and $v_name;
I have it storing the $h_name no problem; but i do not know how to make it store both $h_name and $v_name separately as they are both values in the column "team_name" from "teams" table. So I just need to somehow make it so when i get my results it can tell the difference between the two different "team_names" and I can store them in the two different variables…
If this is not clear please let me know.
Thanks!
***** UPDATE 10:49pm EST 2/5/2015
have made some progress on this but my query is not working; I think it is a problem with the aliases and such are not right; here is my non-working query as it is right now:
$sth = $dbh->prepare("SELECT home_team.team_name as home_team_name, visiting_team.team_name as visiting_team_name,
h_team, v_team, po_div_id, round, game_id, date, timestamp, h_score, v_score, tom_game_id, playoff_name FROM playoff_schedule
LEFT OUTER JOIN teams as home_team on playoff_schedule.h_team = teams.team_id
LEFT OUTER JOIN teams as visiting_team on playoff_schedule.v_team = teams.team_id
LEFT OUTER JOIN playoff_divisions on playoff_schedule.po_div_id = playoff_divisions.po_div_id
WHERE tom_game_id=$array_game_id6");
$sth->execute();
$article_list = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($article_list as $row => $link) {
$h_team=$link['h_team'];
$v_team=$link['v_team'];
$po_div_id=$link['po_div_id'];
$round=$link['round'];
}
if anyone can spot a problem with my new query I would really appreciate it!
I think what you are trying to do is:
select home_team.team_name as home_team_name,
visiting_team.team_name as visiting_team_name
from playoff_schedule
join team as home_team on playoff_schedule.h_team = teams.team_id
join team as visiting_team on playoff_schedule.v_team = teams.team_id
You can join to the same table as many times as you want to. In this case, it makes sense, because you really are trying to get two different bits of information.
Based on your last edit, the following query appears to work:
SELECT home_team.team_name AS home_team_name,
visiting_team.team_name AS visiting_team_name,
h_team,
v_team,
playoff_schedule.po_div_id,
round,
game_id,
date,
timestamp,
h_score,
v_score,
tom_game_id,
playoff_name
FROM playoff_schedule
LEFT OUTER JOIN teams AS home_team
ON playoff_schedule.h_team = home_team.team_id
LEFT OUTER JOIN teams AS visiting_team
ON playoff_schedule.v_team = visiting_team.team_id
LEFT OUTER JOIN playoff_divisions
ON playoff_schedule.po_div_id = playoff_divisions.po_div_id
WHERE tom_game_id=$array_game_id6
You can check the query and the schema at: SQLFiddle
A couple of thing that might be happening:
Is the query itself running?
What happens if you run the query in a mySQL client?
Are there any PHP errors in your log?
Could you post the schema itself?
Is $array_game_id6 actually an array of values? In that case, you need to use "in" as opposed to "=" in your where clause.
With regard to your updated query, I think the main thing you are missing is using the aliases in your JOIN conditions. You should keep your table aliases consistent throughout your query. Also, IMO its better to keep table aliases short so they are easier to read:
So applying those things to your query:
SELECT h.team_name as h_team_name, v.team_name as v_team_name, s.h_team, s.v_team, s.po_div_id, s.round, s.game_id, s.date, s.timestamp, s.h_score, s.v_score, s.tom_game_id, s.playoff_name
FROM playoff_schedule s
LEFT OUTER JOIN teams h ON (
s.h_team = h.team_id
)
LEFT OUTER JOIN teams as v ON (
s.v_team = v.team_id
)
LEFT OUTER JOIN playoff_divisions d ON (
s.po_div_id = d.po_div_id
)
WHERE s.tom_game_id = ?
Now I'm not 100% sure of your schema so I may have referenced some of the columns to the wrong table but you should be able to sort that out.

List Down All Non-Paid Students But Having Some Issue

I am trying to list down all the students who dont pay their dues between two date ranges. I first select all the student ids from fee table and then store it in a variable and then compare these ids with student table to list down all non paid students. But my problem is it works only on last id. Let say if i get student id, 1 and 2 then query works only on student id 2. Here is the code.
$query = mysql_query("SELECT student_id,created FROM fee WHERE DATE(created) between '$sqldate1' AND '$sqldate2'");
while($rows = mysql_fetch_array($query)) {
$students = $rows['student_id'];
//echo $students;
$link = mysql_query("SELECT fee.class_id,fee.section_id,fee.student_id,fee.section_group,
fee.student_fee,fee.test_fee,fee.other_charges,fee.created,fee.fee_month,
class.class_id,class.class_name,section.section_id,section.section_name,student.id,
student.student_name FROM fee LEFT JOIN class ON(fee.class_id=class.class_id)
LEFT JOIN section ON(fee.section_id=section.section_id)
LEFT JOIN student ON(fee.student_id=student.id) WHERE student.id !='$students'")
or die(mysql_error());
$num = mysql_num_rows($link);
}
You must specify the table name on the join condition as mentioned below
$link = mysql_query("SELECT fee.class_id,fee.section_id,fee.student_id,fee.section_group,
fee.student_fee,fee.test_fee,fee.other_charges,fee.created,fee.fee_month,
class.class_id,class.class_name,section.section_id,section.section_name,student.id,
student.student_name FROM fee LEFT JOIN class ON(fee.class_id=class.class_id)
LEFT JOIN section ON(fee.section_id=section.section_id)
LEFT JOIN student ON(fee.student_id=student.id) WHERE DATE(fee.created) between '$sqldate1' AND '$sqldate2'")
You are iterating over every student_id from your initial query, and running your second query using a different, single student each time. Since you are overwriting $students, $link, and $num each iteration without storing them somewhere, that data is lost and you will be left with whatever the last iteration of your loop happened to be.
You need to first construct a list of all student_ids which you wish to check against, then use that in a comparison in your second query (which needs to be outside of the while loop).
$students is being overwritten in your while loop with each new student id, leaving it with only the last one. Make $students an array:
$students[] = $row['student_id'];
And changr the second query:
WHERE student.id NOT IN (".implode(",", $students).")
You can just have one query:
SELECT fee.class_id,fee.section_id,fee.student_id,fee.section_group,
fee.student_fee,fee.test_fee,fee.other_charges,fee.created,fee.fee_month,
class.class_id,class.class_name,section.section_id,section.section_name,student.id,
student.student_name FROM fee LEFT JOIN class ON(fee.class_id=class.class_id)
LEFT JOIN section ON(fee.section_id=section.section_id)
LEFT JOIN student ON(fee.student_id=student.id) WHERE student.id NOT EXISTS (SELECT student_id,created FROM fee WHERE DATE(created) between '$sqldate1' AND '$sqldate2');

Echo results of a complicated INNER JOIN query with multiple tables

This is my first question here. I have a complicated SQL database and I need to join different tables which have the same column names.
"event" is a sports match. It contains tournament_stageFK which is linked to tournament_stage table, which contains tournamentFK which is linked to tournament table, which contains tournament_templateFK which is linked to tournament_template table, which contains sportFK which is linked to sport table.
So in order to find out what sport the match is from, I need to do an inner join, otherwise I'd have to open the database millions of times. The only way to do it is this, but I don't know how to display the results. My poor attempt to echo the results is below:
$SQL = "SELECT sport.name,
country.name,
tournament_template.name,
tournament.name,
tournament_stage.name,
event.*
FROM tournament_template
INNER JOIN sport
ON tournament_template.sportFK = sport.id
INNER JOIN tournament ON tournament.tournament_templateFK = tournament_template.id
INNER JOIN tournament_stage ON tournament_stage.tournamentFK = tournament.id
INNER JOIN event ON event.tournament_stageFK = tournament_stage.id
INNER JOIN country ON tournament_stage.countryFK = country.id
WHERE DATE(event.startdate) = CURRENT_DATE()
ORDER BY sport.name ASC,
country.name ASC,
tournament_stage.name ASC,
event.startdate ASC";
$result = mysql_query($SQL);
while($get=mysql_fetch_array($result))
{
echo $result['event.name'];
echo "<br>";
}
Your result is fetched as an array indexed by column name, which is "name" for several of your columns... the table name sport, country, template, etc is not part of the returned index. So you need to provide column names that will be unique
Set an alias for each of your columns (e.g. SELECT sport.name AS sport_name) then reference it by its alias within your echo (e.g. $result['sport_name']).
You need to use column aliases and access those in your fetch call. Instead of event.*, be explicit about the columns you need:
$SQL = "SELECT sport.name AS sportname,
country.name AS countryname,
tournament_template.name AS templatename,
tournament.name AS tournamentname,
tournament_stage.name AS stagename,
/* Use explicit column names instead of event.* */
event.name AS eventname,
event.someothercol AS someother
FROM tournament_template
...etc...
...etc...";
// Later...
while($row=mysql_fetch_array($result))
{
echo $row['eventname'];
echo "<br>";
}

Categories