PDO : get a list of unique similar part of value - php

I'm fetching data with PDO from a table containing 2 fields : comment and date.
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
extract($row);
echo $comment;
echo $date;
}
Which displays a list of all comments.
Now I'm trying to group these comments by month, the main goal is to create some filter menu with a GET value so that only the current month comments are displayed :
<ul>
<li>October 2014</li>
<li>November 2014</li>
<li>December 2014</li>
</ul>
I think I should be fine with the LIKE operator for displaying the results, but what about the menu links generation ?
Main issue : $date is in d/m/Y format, so I have to process before using it :
$created = $date;
$month = $created->format('mY');
Also I can't really know in advance which months are going to be registered in the table, so it have to be "dynamic".
So how do I get a list of every month appearing in the table ? Without redundancy of course. Like
1014
1114
1214
even if there is numerous comments created on October for instance.

You can use MySQL's STR_TO_DATE and DATE_FORMAT functions to return the date in the format you need. For example:
SELECT `comment`, DATE_FORMAT(STR_TO_DATE(`date`, "%d/%m/%Y"), "%m%y") as `date2` FROM `data`
If you need to query all the unique month/year combinations, use DISTINCT:
SELECT DISTINCT DATE_FORMAT(STR_TO_DATE(`date`, "%d/%m/%Y"), "%m%y") as `date2` FROM `data`
Here's a SQL fiddle showing the distinct select.

Related

Format date from mysql query with multiple tables

I have an sql query that I use to display the news section of my website.
I would really love for the dates to be presented as "2nd January, 2012" however as I am selecting all fields from 5 tables I don't know where to put my formatting requirements (I am not selecting individual fields).
My query is below:
$query_newsheadlines = "
SELECT *
FROM
NewsArticles,
NewsArticleCategories,
NewsArticlePhotos,
NewsCategories,
NewsPhotos
WHERE
NewsArticles.id = NewsArticleCategories.newsArticleID
AND NewsArticles.id = NewsArticlePhotos.newsArticleID
AND NewsArticlePhotos.newsPhotoID = NewsPhotos.id
AND NewsArticleCategories.newsCategoryID = NewsCategories.id
AND NewsCategories.SectionID = 201
ORDER BY NewsArticles.publishDate DESC";
Any ideas would be appreciated :)
update the column my date is located in is NewsArticles.publishDate
you need to specify what column do you want to be formatted (just don't be lazy on specifying the column). Use DATE_FORMAT
SELECT DATE_FORMAT(CURDATE(),'%D %M, %Y')
SQLFiddle Demo
Other Source(s)
DATE_FORMAT()

how to output database entries by date in DD/MM/YY format?

i am outputting database entries with the following code:
<div id="main_area">
<div id="container">
<div id="php_container" role="main">
<?php
include('connect_it.php');
$sqlget= "SELECT * FROM dbtablename";
$sqldata= mysqli_query ($dbcon,$sqlget) or die('this is an error');
while ($row = mysqli_fetch_array($sqldata, MYSQLI_ASSOC)) {
echo $row[ 'li' ] ;
}
?>
</div>
</div>
</div>
on page load, i'd like the database entries to be ordered by their date (from most recent to least recent) which is stored in a mysql field called 'added' in the format DD/MM/YY.
i'm not sure if it can be done, but as another option, the date is within a span defined by <span id="date">date: 27/11/11</span> so perhaps this span could be used to order the data?
so my question is, how can i make the initial output ordered by date from most recent to least recent?
i have tried:
$sqlget= "SELECT * FROM dbtablename ORDER BY added ASC";
but i got unexpected results.
thank you.
If your added column is a DATE, DATETIME or TIMESTAMP type you can use DATE_FORMAT like so,
$sqlget= "SELECT *, DATE_FORMAT(added,'%d/%m/%y') as addedFormated FROM dbtablename ORDER BY added ASC";
See, https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
Otherwise if it is a string try (it really should be a DATE type though),
$sqlget= "SELECT *, STR_TO_DATE(added,'%d/%m/%y') as addedFormated FROM dbtablename ORDER BY STR_TO_DATE(added,'%d/%m/%y') ASC";
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date
A few minor things first (there are more too), <span id="date">...</span> is not valid as the id attribute should be unique, use <span class="date">...</span> instead. Browsers will render it, even render it correctly in most cases, but is not the correct use of an "id" attribute.
Do you need to select all columns in your query? If not, only select the ones you need.
The query you want is:
SELECT * FROM dbtablename ORDER BY added DESC
But this will select all rows and all columns. Now for the tricky part. You say your data is stored in 'dd/mm/yyy' format, so this query will not work as there are about 30 days per month per year. You need to either use a datetime column type, which will store your date data in yyyy-mm-dd 00:00:00 format. As you can see, this will correct all your issues.
Or, as someone else said, use STR_TO_DATE(added,'%d/%m/%y') to extract the data.
Then, on your extracted data, in PHP, use (where $var is your date value):
echo date('d/m/y',strtotime($var));
Hope that helps.

SQL to get DISTINCT date values from a table

I have a field in a table named startdate and what I would like to do is run as little queries as possible to obtain a list that would display as the following:
2012
January
March
October
2011
September
November
The only dates that I want to show per year are the dates where there is a record for.
Any help or pointers appreciated.
Thanks
This query can be used to find all distinct Year/Month combinations in a table for a given date (here start date).
SELECT YEAR(startdate) AS DYear, MONTH(startdate) AS DMonth
FROM tablename
GROUP BY YEAR(startdate), MONTH(startdate)
After you have your results back in whatever way you choose to get them you can do something like this:
$year = 0;
while ($row) { //loop through your rows here using while or foreach
if($year != $row['DYear']){
echo '<h1>'.$row['DYear'].'</h1>';
$year = $row['DYear'];
}
echo '<ul>';
echo '<li>'.$row['DMonth'].'</li>';
echo '</ul>';
}
select distinct column1, column2, column3... from table where columnx <> "" order by year, month
Using PDO, you could do something like:
$dbh = new PDO("mysql:dbname=$dbname", $username, $password);
$qry = $dbh->query('
SELECT DISTINCT
YEAR(startdate) AS year,
MONTHNAME(startdate) AS month
FROM
my_table
ORDER BY
startdate
');
if ($qry) {
$row = $qry->fetch();
while ($row) {
$current_year = $row['year'];
echo '<h1>',htmlentities($current_year),'</h1><ul>';
do {
echo '<li>',htmlentities($row['month']),'</li>';
} while ($row = $qry->fetch() and $row['year'] == $current_year);
echo '</ul>';
}
}
SELECT DISTINCT YEAR(startdate), MONTHNAME(startdate)
FROM mytable
ORDER BY YEAR(startdate) desc, MONTH(startdate) asc;
should do the trick, however the output will be:
2012 January
2012 March
2012 October
2011 September
2011 November
you can use the code given by eggyal to convert this into a format that you are looking for. Note that you will need to order on MONTH and not MONTHNAME (unless you want alphabetical order)
As other posts have given your answer, I am going to provide information on why these answers work.
In an SQL select statement you can provide keywords. Specifically for MySQL you can provide ALL, DISTINCT, DISTINCTROW(and others unrelated to distinct rows).
The latter two options are actually the same option and yield the same results. The default select statement with no keyword uses ALL which returns all results. By passing in DISTINCT you eliminate any duplicate entries.
A duplicate entry is an entry where all the fields are the same, However, it should be noted that if you have an auto-incrementing primary key each row is distinct from the last as the pk is different. In order to select a distinct value with this kind of setup, you would need to specify a separate column name that is truly distinct.
For more reading on MySQL SELECT statements refer to the users guide's select section.
Hopefully I didn't provide information you have already gathered from the provided answers, but I have always found understanding "why" and "how" often allow me to understand when a particular solution will work, as well as when it won't work.

How to select certain data from a same field

Now currently facing a problem that is..
My table name is schedule
One of the data field is 'Depart'
the record is
row 1 = 19-08-2012 08:00:00AM,
row 2 = 19-08-2012 12:00:00PM,
row 3 = 20-08-2012 07:00:00PM,
I just want to display the date only and it is distinct
mysql_query(Select distinct depart from schedule);
This display date and the time.
Any one here know how to display the date only?
Example
SQL (recommended)
SELECT DISTINCT DATE( depart )
FROM `tbl`
PHP
$d = "19-08-2012 08:00:00AM";
echo date("d-m-Y",strtotime($d));
You can use DATE_FORMAT() function in the Mysql, as follows :
select DATE_FORMAT(distinct(Depart),'%m-%d-%Y') from schedule
Yes, use DATE:
SELECT DISTINCT DATE(`depart`) FROM `schedule`

MySQL & PHP: summing up data from a table

Okay guys, this probably has an easy answer but has been stumping me for a few hours now.
I am using PHP/HTML to generate a table from a MySQL Table. In the MySQL table (TimeRecords) I have a StartTime and EndTime column. In my SELECT statement I am subtracting the EndTime from the StartTime and aliasing that as TotalHours. Here is my query thus far:
$query = "SELECT *,((EndTime - StartTime)/3600) AS TotalPeriodHours
FROM TimeRecords
WHERE Date
BETWEEN '{$CurrentYear}-{$CurrentMonth}-1'
AND '{$CurrentYear}-{$CurrentMonth}-31'
ORDER BY Date
";
I then loop that through an HTML table. So far so good. What I would like to do is to add up all of the TotalHours and put that into a separate DIV. Any ideas on 1) how to write the select statement and 2) where to call that code from the PHP/HTML?
Thanks in advance!
Try this
$query= "
SELECT ((EndTime - StartTime)/3600) AS Hours, otherFields, ...
FROM TimeRecords
WHERE
Date BETWEEN '{$CurrentYear} - {$CurrentMonth} - 1'
AND '{$CurrentYear}-{$CurrentMonth} - 31' ";
$records =mysql_query($query);
$sum= 0;
while($row=mysql_fetch_array($records))
{
echo"$row['otherFields']";
echo"$row['Hours']";
$sum+=$row['Hours'];
}
echo" Total Hours : $sum ";
Just use a single query with a Sum(). You could also manually calculate it if you're already displaying all rows. (If paginating or using LIMIT, you'll need a separate query like below.)
$query = "
SELECT Sum(((EndTime - StartTime)/3600)) AS SumTotalPeriodHours
FROM TimeRecords
WHERE
Date BETWEEN '{$CurrentYear} - {$CurrentMonth} - 1'
AND '{$CurrentYear}-{$CurrentMonth} - 31'
";
You can do this in the same query if you have a unique id using GROUP BY WITH ROLLUP
$query = "
SELECT unique_id,SUM((EndTime - StartTime)/3600) AS TotalPeriodHours
FROM TimeRecords
WHERE Date BETWEEN '{$CurrentYear}-{$CurrentMonth}-1'
AND '{$CurrentYear}-{$CurrentMonth}-31'
GROUP BY unique_id WITH ROLLUP
ORDER BY Date
";
In this instance the last result from your query with contain NULL and the overall total. If you don't have a unique ID you will need to do it in PHP as per Naveen's answer.
A few comments on your code:
Using SELECT * is not considered good practice. SELECT the columns you need.
Not all months have a day 31 so this may produce unexpected results. If you're using PHP5.3+, you can use
$date = new DateTime();
$endDate = $date->format( 'Y-m-t' );
The "t" flag here gets the last day of that month. See PHP docs for more on DateTime.

Categories