SQL query inside a loop in a loop
Hey everybody. I am trying to print out a schedule with thirty minute intervals and would like to query a DB to get whatever thing is happening at that time. If i manually enter the time (hour, minute, am/pm(months, year, day work as is)) i get events. It's just when i let the query pull the time from the loop this doesnt work. Any ideas?
$day = date('d');
$year = date('Y');
$month 开发者_开发知识库= date('m');
$start = mktime(0,0,0);
$thing_query="SELECT thing FROM things WHERE day='$day' AND month='$month' AND year='$year' AND hour='$hour' AND minute='$minute' AND ampm='$am'";
$result=mysql_query($thing_query);
for($min = 0; $min < 24 * 60 * 60; $min += 30 * 60)
{
$hour=date("h", $start + $min);
$minute=date("i", $start + $min);
$am=date("A", $start + $min);
while ($row=mysql_fetch_array($result)) {
$thing = $row[0];
}
printf("<tr><td>%s</td><td>$thing</td></tr>",
date("g:i a", $start + $min));
}
Variable references in a string are only valid at assignment; they don't continue to update if you change those variables, so when you do
$thing_query="SELECT thing FROM things WHERE day='$day' AND month='$month' AND year='$year' AND hour='$hour' AND minute='$minute' AND ampm='$am'";
it's equivilent to
$thing_query="SELECT thing FROM things WHERE day='15' AND month='2' AND year='2011' AND hour='' AND minute='' AND ampm=''";
because $hour, $minute and $am haven't been set, and thus the query returns nothing.
Even if they were, updating the string won't update the database query; you'll need to call mysql_query() on the new string to get that data.
If you move the $thing_query= and $res= lines to just before the while loop this should work, although it will only return the last event in each timeslot, because you're overriding $thing each time you go through the loop. It will also continue to list an event in every timeslot until it reaches a new one, because you're not clearing $thing.
As Andy says, this isn't currently a very efficient way to do what you want, but since you're presumably just starting out I'm guessing its more important to you for now that it works rather than being efficient, so hopefully this helps for now.
I would imagine this is because you are not setting hour minute and ampm before you query the database.
You probably need to requery the DB every cycle through the loop with the new hour, minute etc, however there is probably a more efficient way of doing this... i.e. Hit the db once for the whole days data, then use PHP to iterate out the info. 1 db call insted of 24*60*60
The below code is untested so please call me up on it if it doesn't work entirely but it should give you an idea:
$day = date('d');
$year = date('Y');
$month = date('m');
$start = mktime(0,0,0);
$thing_query="SELECT thing FROM things WHERE day='$day' AND month='$month' AND year='$year';
$result=mysql_query($thing_query);
while ($row=mysql_fetch_array($result)) {
// Loop through your hours mins etc and output desired values
}
}
All the data you need is stored in mysql_fetch_array($result)
you can then loop through that where required. You dont want to be hitting the DB more than is necessary.
From what i can see you have the PHP to be able to do it - i think its a structure thing you are struggling with.
Your loop structure is wrong - you are consuming the entirety of the query result set on your first run around the parent for
loop. And your internal while
loop is simply setting $thing
to the value of one field repeatedly, so $thing ends up being the LAST value returned from the query.
comment followup. An inefficient method of doing what you want would be:
$day = ...
$year = ...
$month = ...
$start = ...
for ($min = 0; ....) {
$hour = ...
$min = ...
$am = ...
$thing_query = "SELECT ...."
$result = mysql_query($thing_query) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
printf(.... $row[0] ... );
}
}
But this would run a query for every single time point you're checking for. Why not just store the event's date/time in a single date/time field. YOu can reduce your query to
SELECT ... WHERE timestampfield BETWEEN startdatetime AND enddatetime
then use the results of that in PHP to build up your events. A single "larger" query would be more efficient than a long series of "small" ones.
You mixed up the order of your statements pretty badly. Here's the right way, and some additional comments:
$day = date('d');
$year = date('Y');
$month = date('m');
$start = mktime(0,0,0);
for($min = 0; $min < 24 * 60 * 60; $min += 30 * 60)
{
$hour=date("h", $start + $min);
$minute=date("i", $start + $min);
$am=date("A", $start + $min);
// you must set the string after $hour/$minute/$date have the right value
$thing_query="SELECT thing FROM things WHERE day='$day' AND month='$month' AND year='$year' AND hour='$hour' AND minute='$minute' AND ampm='$am'";
// query the database with the string
$result=mysql_query($thing_query);
// put things in an array
$things = array();
while ($row=mysql_fetch_array($result)) {
$things[] = $row[0];
}
// join the array so I have a comma separated list of things
$listOfThings = implode(", ", $things);
// ALWAYS use htmlspecialchars when sending data from the database to the browser!!!!
echo "<tr><td>" . date("g:i a", $start + $min) . "</td><td>" . htmlspecialchars($listOfThings) . "</td></tr>";
}
精彩评论