I'm revising the navigation of my news system and would like to do so using minimal MySQL queries. I've managed to get it all down to one query, but something seems to be wrong. Any help would be greatly appreciated.
What I wish to achieve is (literally) the following overview of events, hierarchically sorted per year and month, along with the number of events in that month:
2012
--04 (3)
--02 (1)
--01 (1)
2011
--12 (3)
--11 (2)
--10 (3)
--09 (1)
--07 (1)
--02 (1)
I'm very close. My query is as follows:
SELECT start_date, date_format(start_date, "%Y") as year, date_format(start_date, "%m") as month FROM event ORDER BY start_date desc
Then, my PHP loop is as follows:
$year = '';
$year_counter = 0;
$month = '';
$month_counter = 1;
while($row = mysql_fetch_assoc($result)){
if ( $year != $row['year'] ) {
$year = $row['year'];
$output .= $year.'<br />';
}
if ( $month == $row['month'] ) {
$month_counter++;
} else {
$month = $row['month'];
$output .= '--'.$month.' ('.$month_counter.')<br />';
$month_counter = 1;
}
}
Which generates everything perfectly, except for the number of events per month, that seem to be always one line off (you please see the difference with the wanted result above).
2012
--04 (1)
--02 (3)
--01 (1)
2011
--12 (1)
--11 (3)
--10 (2)
--09 (3)
--07 (1)
--02 (1)
I've been tinkering with this all afternoon without success. I think it's best to leave it to the absolute experts. A hand please?
Currently, you're printing the month_counter before you've updated it for the next month. Before your while loop, you need to initialize your variables based on the first row retrieved rather than the default values.
if ($row = mysql_fetch_assoc($result){
$year = $row['year'];
$month = $row['month'];
$month_counter = 1; //1 because you've already counted the first article
// print out the first year
$output .= $year.'<br />';
while($row = mysql_fetch_assoc($result){
if ( $year != $row['year'] ) {
$year = $row['year'];
$output .= $year.'<br />';
}
if ( $month == $row['month'] ) {
// You've found one more article for this month, so increment the count
$month_counter++;
} else {
// You've hit a new month, so print out the information you collected
// about the previous month
$output .= '--'.$month.' ('.$month_counter.')<br />';
$month = $row['month'];
$month_counter = 1;
}
}
}
The difference between outputting the year and outputting the month, is that you also want to output the count associated with the month, whereas there is no additional information associated with the year. You have to print that before you change to the next month.
Your
$month = $row['month'];
is in the wrong place. It sets the $month-variable for a new month, but it has been counting the number for the months before it.
The first time it runs through the while-loop
if ( $month == $row['month'] )
can never be true, so it goes into the else-statement, displaying the month and the count (which is 1 because you set it to 1 at the top)...
I probably made some mistake here, but you could count events per Year-month and group them accordingly.. something like
SELECT start_date, date_format(start_date, "%Y") as year, date_format(start_date, "%m") as month, date_format(start_date, "%Y%m") gr, COUNT(id)
FROM event
ORDER BY start_date desc
GROUP BY gr
Related
I have problem getting the year
I have here in my database year of 11/11/2016 - 11/13/2015 - 11/13/2014
the problem is I want to get that year just deducting current year
so if the current year is 2017 I want to get 2016,2015,2014 , and the next year
2018 the year will get is 2017,2016,2015
$selectmemberpaid = mysql_query("SELECT
memberid,StartDate,EndDate,tblpayments.activityname,amount_paid FROM
tblattend_activity LEFT JOIN tblpayments ON tblattend_activity.memberid =
.profile_id WHERE memberid='201400001'");
That is my query..
and this is my while loop
while ($rows = mysql_fetch_assoc($selectmemberpaid)) {
# code...
$dateTimestamp = strtotime($rows['StartDate']);
$year = date("Y", $dateTimestamp);
}
You can get the year from a date string by doing something like this:
$dateTimestamp = strtotime('2015-12-12');
$year = date("Y", $dateTimestamp);
echo $year;
Once you get it you can add or subtract to get the previous/next year (after converting the value into an integer).
I'm not sure I understand what you're asking but:
Query!
$rest = substr(date('d-m-Y'), 6);
$rep = $idz->query("SELECT * FROM stack1 where SUBSTR(date_depart, 6) < $rest
order by SUBSTR(date_depart,6) desc limit 3");
while ($row = $rep->fetch())
{
echo $row['date_depart'];
//echo "<br>";
}
$rep->closeCursor();
Result
I am trying to build a custom car schedule calendar for car rental company which to show all free days in white on the attachment file and busy days in red color. Till now I succeeded to draw the calendar with correct days and style colors but I want also in the td cell to display the customer names for each reservation. Also if possible to merge reservation cells
This is my working code, but whatever I tried I could not pass customer names in dates array so I could somehow recognize which reservation day is for each customer.
$datstart2 = "2017-01-01 00:00:00" ;
$datend2 = "2017-01-31 00:00:00" ;
foreach($cars as $cid){
$query2 = 'select rr.resnumber, DATE_FORMAT( `datestart` , "%Y-%m-%d" ), DATE_FORMAT( `dateend` , "%Y-%m-%d" ), rr.cl_name, rr.totdays from res_cars rc,res_reservations rr where rr.carid="'.$cid.'" and datestart > now() and (datestart BETWEEN "'.$datstart2.'" AND "'.$datend2.'") group by resnumber order by datestart ASC';
$result2=mysql_query($query2) or die($query2);
$num_rows2=mysql_num_rows($result2);
for($j=0;$j<$num_rows2;$j++){
$row2=mysql_fetch_row($result2);
$current = strtotime($row2[1]);
$last = strtotime($row2[2]);
//here I generate array that contains all busy days between datestart & dateend for each reservation
while( $current <= $last ){
$dates1[] = date('Y-m-d', $current);
$current = strtotime($step, $current);
}
}
//here I generate a new array with all days without reservation for January for the car
$dates2 array consists all days in the month
$emptydays=array_diff($dates2,$dates1);
foreach($dates as $date){
//here I draw table cell with different styles if the dy is reserved or not
if(in_array($date,$emptydays)){
echo '<td class="emptyday">.</td>';
} else {
echo '<td class="busyday">X</td>';
}
}
}
The problem is that I wish table cells from type busyday to look like:
echo '<td class="busyday">Customer names here</td>';
but whatever I tried had no success. Can you guys help me please and show me the correct way to printout the customer names (cl_name) for each reservation and make it look like:
echo '<td class="busyday">Customer names here</td>';
My approach would be to write objects to the $dates1/$dates array that contain both the date and the array. This way both properties would be available in your second loop. One to search for the date, and the other to access the name.
First section:
$datstart2 = "2017-01-01 00:00:00" ;
$datend2 = "2017-01-31 00:00:00" ;
foreach($cars as $cid){
$query2 = 'select rr.resnumber, DATE_FORMAT( `datestart` , "%Y-%m-%d" ), DATE_FORMAT( `dateend` , "%Y-%m-%d" ), rr.cl_name, rr.totdays from res_cars rc,res_reservations rr where rr.carid="'.$cid.'" and datestart > now() and (datestart BETWEEN "'.$datstart2.'" AND "'.$datend2.'") group by resnumber order by datestart ASC';
$result2=mysql_query($query2) or die($query2);
$num_rows2=mysql_num_rows($result2);
for($j=0;$j<$num_rows2;$j++){
$row2=mysql_fetch_row($result2);
$current = strtotime($row2[1]);
$last = strtotime($row2[2]);
//here I generate array that contains all busy days between datestart & dateend for each reservation
while( $current <= $last ){
$ODateInfo = new stdClass();
$ODateInfo->date = date('Y-m-d', $current);
$ODateInfo->name = $row2[4]
$dates1[] = $ODateInfo;
date('Y-m-d', $current);
$current = strtotime($step, $current);
$datesCompare[] = date('Y-m-d', $current);
}
}
$emptydays=array_diff($dates2,$datesCompare);
Second section:
foreach($dates as $date){
//here I draw table cell with different styles if the dy is reserved or not
if(in_array($date->date,$emptydays)){
echo '<td class="emptyday">.</td>';
} else {
echo '<td class="busyday">' . $date->name . '</td>';
}
}
}
The final code would look something like this: (Note I was unable to test it, although this should point you in the right direction.)
Let me know if you need anything further.
Regards,
James
i need to list total post article archive by years and months like this :
Output(my need):
2014
January(31)
February(28)
March(0)
April(130)
May(450)
June(0)
July(0)
August(0)
September(0)
October(520)
November(20)
December(31)
PHP:
$sql = "SELECT title, YEAR(FROM_UNIXTIME(timestamp)) AS YEAR,
MONTHNAME(FROM_UNIXTIME(timestamp)) AS MONTH,
COUNT(*) AS TOTAL
FROM article GROUP BY YEAR, MONTH ORDER BY YEAR DESC, MONTH ";
$newsdata = DB->fetch($sql);
$currentYear = null;
foreach($newsdata AS $news){
if ($currentYear != $news['YEAR']){
echo '<ul>'.$news['YEAR'].'</ul>';
$currentYear = $news['YEAR'];
}
echo '<li>'.$news['MONTH'].' '.$news['TOTAL'].'</li>';
}
My code worked but print only month if posted article in this month.
Ouput:
2014
January(31)
February(28)
April(130)
May(450)
October(520)
November(20)
December(31)
I need to list all month and print total article for each month. if month not posted article print (0) for this month.
how do can i fix my problem? my code/way is true?!
Your database query won't return a row for a month that has no articles. It doesn't know anything about months. So you need to handle this in code by having an array of all months and looping through that. The alternative would be to alter your schema, have another table with all 12 months, and join on that. But I think the following is easier for you:
$months = array( "January", "February", ... );
Then you can do the following in your output instead:
// Index article counts by month and year for easy lookup
$indexedNewsData = array();
foreach ($newsdata as $news) {
$indexedNewsData[$news['YEAR']][$news['MONTH']] = $news['TOTAL'];
}
// Then print output
foreach($newsdata AS $news){
if ($currentYear != $news['YEAR']){
echo '<ul>'.$news['YEAR'].'</ul>';
$currentYear = $news['YEAR'];
} else {
// Continue here otherwise we will print each year's data 12x
continue;
}
foreach ($months as $month) {
$total = intval($indexedNewsData[$news['YEAR']][$month]);
echo '<li>'.$month.' '.$total.'</li>';
}
}
I have a database table that has two columns eventName|eventDate. I have created a function that takes in a startDate and endDate, I want to display the list of events in a ListView with each date as the header.
In my brief example below, I know I can retrieve the full event listings with SQL. How do I then slot the event headers in so that I can return them in a properly formatted array?
function retrieveEvents($startDate, $endDate) {
// run SQL query
//
if($stmt->rowCount() > 0) {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
// how do I write this part such that I can output event headers in my array
$events = $row;
}
}
}
So my intended output is
1st July 2013 ($startDate)
- Tea with President - 1300h
- Mow the lawn - 1330h
- Shave the cat - 1440h
2nd July 2013
- Shave my head - 0800h
3rd July 2013
4th July 2013 ($endDate)
- Polish the car - 1000h
In your MYSQL query:
SELECT * FROM `yourTableName` WHERE `eventDate` >= $startDate AND `eventDate` <= $endDate
PS: I'm not sure about the quotes arount the variables in your query.
PPS: never use * to select your columns, always only select the columns you need. Here I'm using it because I don't know the names of your columns
I ended up doing my checking in PHP and print a new row only when a different date is detected.
Codes below in case it serves someone's needs in future.
<?php
$currentPrintDay = 0;
$currentPrintMonth = 0;
$currentPrintYear = 0;
echo "<table>"
foreach($reservationsToShow as $row):
// get day, month, year of this entry
$timestamp = strtotime($row['timestamp']);
$day = date('d', $timestamp);
$month = date('m', $timestamp);
$year = date('Y', $timestamp);
// if it does not match the current printing date, assign it to the current printing date,
// assign it, print a new row as the header before continuing
if($day != $currentPrintDay || $month != $currentPrintMonth || $year != $currentPrintYear) {
$currentPrintDay = $day;
$currentPrintMonth = $month;
$currentPrintYear = $year;
echo
"<tr>" .
"<td colspan='100%'>". date('d-m-Y', $timestamp) . "</td>" .
"</tr>";
}
// continue to print event details from here on...
?>
my database table is something like :
id year month
1 2011 november
2 2011 november
3 2011 october
i need to create a query so it return something like that :
2011
november
november
october
What is the correct query syntax to do it in php script ?
Here is the code i used :
<?php
$uid = $_SESSION['uid'];
$sql = "SELECT year, GROUP_CONCAT(month) AS months FROM articles GROUP BY year";
$res = mysql_query ($sql) or die (mysql_error());
if (mysql_num_rows($res) > 0) {
while ($rows = mysql_fetch_assoc($res)) {
foreach ($rows AS $row) {
echo $row['year'] . "<br>";
$months = explode(",", $row['months']);
foreach ($months AS $m) {
echo $m . "<br>";
}
}
}
}
?>
You can use GROUP_CONCAT() to return a comma-separated list of months:
SELECT year, GROUP_CONCAT(month) AS months GROM tbl GROUP BY year
Returns:
2011 november,november,october
Or just select both columns and handle the display/presentation in your code:
SELECT year, month FROM tbl WHERE year = 2011
Returns
2011 november
2011 november
2011 october
In code, loop and only display the year when it changes.
Update Since a code example seems warranted...
// Results from above GROUP_CONCAT() query already fetched & stored in `$rowset`:
while ($row = mysql_fetch_assoc($res)) {
$rowset[] = $row;
}
// Now $rowset is a 2D array containing all rows.
foreach ($rowset as $row) {
// Output the year
echo $row['year'] . "\n";
// months are comma-separated via GROUP_CONCAT()
// explode them into an array
$months = explode(",", $row['months']);
foreach ($months as $m) {
// Output the months
echo $m . "\n";
}
}
If I understood your question correctly, I think a simple "ORDER BY" clause would do the trick for you, something similar to:
SELECT * FROM table_name ORDER BY year DESC
Then, use your scripting language to display the data, a good idea could be (maybe) to fetch the year of the first row, store it in a temporal variable, then loop through the rows and check if the year has changed, if it has, change the value of the aforementioned variable, something like this:
$current_year = $data_set[0]['year'];
foreach ( $data_set as $data_row )
{
$current_year = ( $data_row['year'] != $current_year) ? $data_row['year'] : $current_year;
//Do something with it and/or the rest of the data
}
Hope this was of any help.
Cheers.