I have a somewhat-social-network logging project which let users input any activity they have done the whole day.
On my db I have a ‘logs’ table which have the following fields:
| log_id | log_content | log_date | log_author |
My problem is, how can I do a query which would fetch the first n days then display its result in a grid view like this:
| Monday, December 7, 2013
| log_content, log_author, 6 AM | log_content, log_author, 8:30 AM | ...|
| Tuesday, December 8, 2013
| log_content, log_author, 7:10 AM | log_content, log_author, 12:00 NN | log...|
| Wednesday, December 9, 2013
| log_content, log_author, 6:30 PM |
| Thursday, December 10, 2013
| log_content, log_author, 9:53 AM | log_content, log_author, 4:02 PM | ...|
| Friday, December 11, 2013
| log_content, log_author, 1:34 PM |
I know I can’t do a query for the whole ‘logs’ table since it will lead to bottleneck when the logs grow. I was thinking of doing a query in bits, and when the user scrolls down, another background query would run for the next set of data to display(using limits and offsets).
My query as of the moment looks like this:
function fetch_logs($group_id, $limit, $offset){
$this->db->select('l.log_id, l.log_date, l.log_content, u.username');
$this->db->from('logs AS l');
$this->db->join('log_group_ref AS r', 'l.log_id = r.log_id');
$this->db->join('users AS u', 'l.log_author = u.user_id');
$this->db->where('r.group_id', $group_id);
$this->db->limit($limit, $offset);
return $this->db->get()->result_array();
}
But I have no idea how to group the queried data by days and lay them into grid.
I’m using Twitter’s Bootstrap with grid so I can lay down each log into a grid nicely then just add scroll bars if there are more logs.
Update:
So I updated my code based on raheel shan’s second method but I can’t seem to get the data that I wanted until I added:
$this->db->group_by(l.log_date);
basing on Exander’s code which fetch the correct set of data although not formatted same as raheel shan’s.
So out of those two, here’s my updated query:
$select = array(
"DATE_FORMAT(l.log_date,'%a , %b %d , %Y') AS LogDate",
"GROUP_CONCAT(l.log_id) AS LogIDs",
"GROUP_CONCAT(l.log_content) AS LogContents",
"GROUP_CONCAT(u.username) AS LogAuthors",
"GROUP_CONCAT(DATE_FORMAT(l.log_date,'%h:%i %p')) AS LogTimes"
);
$this->db->select($select);
$this->db->from('logs AS l');
$this->db->join('log_group_ref AS r', 'l.log_id = r.log_id');
$this->db->join('users AS u', 'l.log_author = u.user_id');
$this->db->where('r.group_id', $group_id);
$this->db->group_by('l.log_date');
$this->db->limit($limit, $offset);
return $this->db->get()->result_array();
Now, I’ll have to deal with exploding each LogContents, LogAuthors, LogTimes and group them back in array. I need to study raheel shan’s code again.
Update:
I finally got all the things I need to achieve this. I’ll mark raheel shan’s as accepted since I can only accept one. Though Exander’s is also correct plus lesser code which make it great.
Here is how you can do it.
View Demo
Here
And in Codeigniter
Learning Points
Left Joins
Group_Concat
Concat
DATE_FORMAT
EDITS :
2nd Method
if you want to do it with php it is easy. Here is how you can do it. First Model function
And Now in Controller function