I have got this results of a query:
(book_id, yr)
37 2014
37 2012
35 2013
35 2012
35 2011
I would like to echo it like this
book id is 37 from 2014
editions available are 2014 and 2012
One way would be to group them inside a container, then just use min and max:
// grouping
$container = array();
while($row = your_fetch_assoc($result_set)) {
$container[$row['book_id']][] = $row['yr'];
}
// then comes the presentation
foreach($container as $book_id => $year) {
$to = max($year);
$from = min($year);
echo "
book id is {$book_id} <br/>
editions available are {$to} and {$from} <br/><br/>
";
}
$years = array();
$id = 0;
foreach($row as $r){
if( $r['book_id'] != $id && $id != 0){
echo "book id is ".$id." editions available are ".implode('and ', $years);
$years = array();
$id = 0;
}
$id = $r['book_id'];
$years[] = $r['yr'];
}
echo "book id is ".$id." editions available are ".implode('and ', $years);
with that you iterate over you books and collect the years. Every time you find a new ID you echo the old entry with all the years you collectet. In the end you echo the last entry aswell.
Related
i have a age data:
18,25,36,20,23,21,31,
Using php how i can show like this data?
10 to 20 years = 1 people, 20 to 30 years = 4 people, 30 to 40 years = 2 people
You could try something like this. It uses array_map to divide all values in the data by 10 (thus putting them in groups), then array_count_values to count the number of people in each group.
$ages = [18,25,36,20,23,21,31];
$groups = array_count_values(array_map(function ($v) { return (int)($v / 10); }, $ages));
for ($i = 0; $i <= max(array_keys($groups)); $i++) {
echo $i*10 . " to " . ($i*10+9) . " years: " . (isset($groups[$i]) ? $groups[$i]: 0) . "\n";
}
Output:
0 to 9 years: 0
10 to 19 years: 1
20 to 29 years: 4
30 to 39 years: 2
Update
If you don't want to display groups that have no people in them, use this loop instead:
for ($i = 0; $i <= max(array_keys($groups)); $i++) {
if (isset($groups[$i])) echo $i*10 . " to " . ($i*10+9) . " years: " . $groups[$i] . "\n";
}
Output:
10 to 19 years: 1
20 to 29 years: 4
30 to 39 years: 2
Demo on 3v4l.org
There are many ways but I will prefer directly from mysql query, Something like this
SELECT IF (`age` < 10, '0 to 10 years',
IF(`age` > 10 AND `age` < 20, '10 to 20 years',
IF(`age` > 20 AND `age` < 30, '20 to 30 years', 'more than 30 years')
)
) AS age_group,
count(*) as `counts`
FROM `table_name`
Group by `age_group`
You can refer this answer to calculate age from DOB stored in database
$ages = [18,25,36,20,23,21,31];
$years = array(); // floor range
foreach ($ages as $age)
{
$m = (int)($age / 10);
(isset($years[($m*10)])) ? $years[($m*10)]++ : $years[($m*10)] = 1;
}
var_dump($years); // output: array(3) { [10]=> int(1) [20]=> int(4) [30]=> int(2) }
This code collected the birthday dates from your database and groups them for you in your desired ranges.
//Please update this section to grant access to your database
$username = 'root'; //Your Database Username
$password = ''; //Your Database Password
$database = 'test_sample'; //Your Database Name
$table_name = 'ages'; //Your Table Name
$column_name = 'date_of_birth'; // The Column where the birthday dates can be accessed
$query = 'SELECT `'.$column_name.'` FROM `'.$table_name.'`';
$db_connection = mysqli_connect('localhost', $username, $password, $database);
$result = mysqli_query($db_connection, $query);
$current_ages = [];
$now = new DateTime();
while($data = mysqli_fetch_array($result)) {
$date = new DateTime($data[$column_name]);
$interval = $now->diff($date);
$current_ages[] = $interval->y;
}
// $current_ages = [18,25,36,20,23,21,31];
$desired_range = [
[10,20], [21,30], [31,40], [41,50]
];
$result = [];
foreach($current_ages as $data) {
foreach($desired_range as $index => $range) {
if($data >= $range[0] && $data <= $range[1]) {
(isset($result[$index]))? $result[$index]++ : $result[$index] = 1;
break;
}
}
}
foreach($desired_range as $index => $range) {
$count = (isset($result[$index]))? $result[$index] : 0;
echo $range[0]." to ".$range[1]." years = ".$count.' <br/>';
}
I am creating an archives navigation on my website and have found a few posts regarding how to do it and have pulled together some code, but can't seem to get it to work.
I want it to display like:
January 2015 (9)
December 2014 (8)
November 2014 (10)
October 2014 (15)
...
Here's the code :
$sql = "SELECT YEAR(timestamp_published) AS 'year', Month(timestamp_published) AS 'month', COUNT(id) AS 'count' FROM table GROUP BY YEAR(timestamp_published), MONTH(timestamp_published) DESC";
$data = $db->query($sql);
while($row = $db->fetch_assoc()) {
$data[$row['year']][$row['month']] = $row['count'];
}
foreach ($data as $year => $months) {
echo archive_date($month).' ';
foreach ($months as $month => $count) {
echo $year.' ('.$count.') (' . $data->id . ')<br/>';
}
}
}
Thank you! I ended up solving my own issue. I was building this in a class and there were a couple of issues. I've got the code working now, here it is for anyone in the future.
$sql = "SELECT YEAR(timestamp_published) AS 'year', MONTH(timestamp_published) AS 'month', COUNT(`publish`) AS 'count' FROM ".static::$table_name." GROUP BY YEAR(timestamp_published) DESC, MONTH(timestamp_published) ASC";
$result = $db->query($sql);
$data = array();
while($row = $result->fetch_assoc()) {
$data[$row['year']][$row['month']] = $row['count'];
}
foreach ($data as $year => $months) {
echo '<strong>'.$year.'</strong><br/><br/>';
foreach ($months as $month => $count) {
$dateObj = DateTime::createFromFormat('!m', $month);
$monthName = $dateObj->format('F'); // March
echo $monthName . ' ('.$count.')<br/>';
}
echo '<hr/>';
}
It actually comes out looking like this:
2015
January (3)
February (5)
March (6)
...
2014
January (7)
February (9)
...
I think you are looking to get the string representation of the month (bit unclear) but that can be achieved by using date() like so
date ("F", $month)
so in your case
echo date ("F", $month) . ' ' . $year.' ('.$count.')<br/>';
I make a page, that display records from database,in group of 10 records per page using paginition concept,
i wanna print Like: Month name/Year.
That month and year is distinct form that page means of 10 records.
Suppose page number 10 contains 10 records with 3 distinct month named Dec 2011 , Jan 2012 and, March 2012,
In this case i want to print Month: Dec/2011 ,Jan,March/2012
Thanks in advance..
If your date is stored like you write it: Dec 2011, Jan 2012 then you should do like this
$arr = array();
$sql = mysql_query(__YOUR_SQL__);
while($row = mysql_fetch_array($sql)) {
$date = explode(" ", $row['date']);
if(!array_key_exists($date[1], $arr))
$arr[$date[1]] = array();
array_push($arr[$date[1]], $date[0]);
}
foreach($arr as $key => $value) {
if(count($value) == 1)
echo $value[0] . '/' . $key;
else
echo implode(", ", $value) . ' ' . $key;
}
I have a list of mysql timestamps.
I want to produce an html menu, which has got years as first LI and months as nested LI.
for example:
2012 ->
december,
may,
april.
2011 ->
november,
january.
2010 ->
april,
march,
february.
as you see, I want the menu to be an array of years and within months, just the months (and years) which I have in my database.
It's simple for sure, but I can't realize how to perform this.
I'm querying all my timestamps and cycling them, but then when I have to fill the array I can't manage.
The SQL you want is probably something like this:
SELECT YEAR(date) AS year, MONTH(date) AS month, COUNT(*) AS entries FROM my_table
GROUP BY year,month ORDER BY year ASC, month ASC;
And the code would be:
$previous_year = null;
foreach ($result_rows as $row) {
if ($previous_year == null || $row['year'] != $previous_year) {
if ($previous_year != null) {
echo '</ul>/li>';
}
echo '<li><span class="year">'.$row['year'].'</span><ul>';
$previous_year = $row['year'];
}
echo '<li>'.$row['month'].' ('.$row['entries'].')</li>';
}
if ($previous_year != null) {
echo '</ul></li>';
}
Edit:
Alternative PHP based on another answer, this is tidier:
$grouped = array();
foreach ($result_rows as $row) {
$grouped[$row['year']][$row['month']] = $row;
}
foreach ($grouped as $year => $months) {
echo "<li>$year";
echo "<ul>";
foreach ($months as $month => $row) {
echo "<li>$month (".$row['entries'].")</li>";
}
echo "</ul></li>";
}
Have you tried something like this?
<?php
// this would've been pulled from mysql
$data = array(
array('date' => "2010-11-12 12:34:56", 'some' => 'data'),
array('date' => "2010-12-12 12:34:56", 'some' => 'data'),
array('date' => "2010-12-13 12:34:56", 'some' => 'data'),
array('date' => "2011-01-01 12:34:56", 'some' => 'data'),
);
$grouped = array();
foreach ($data as $row) {
$year = substr($row['date'], 0, 4);
$month = substr($row['date'], 6, 2);
$grouped[$year][$month][] = $row;
}
var_dump($grouped);
You must group your queries using GROUP BY , and use loop in PHP which create suitable structure.
In slight peusdo code.
$r = query(SELECT * FROM TBL_WHATEVER ORDER BY TS ASC);
$last_year = null;
while($row as mysql_fetch_assoc($r)){
$year = date('Y', $r['ts']);
if($year != $last_year){
echo $year;
$last_year = $year;
}else{
$month = 1;
while($month < 12){
echo date('F', $r['ts']);
}
}
}
There are many posts about it like this one:
PHP: Loop through all months in a date range?
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.