CakePHP - SQL Query to join 3 tables - php

i have 3 tables
News(id, year_id, month_id, title, description) where year_id and month_id are foreign keys from tables
years(id,...) and
months(id,...)
respectively.
2014 - 2015 - 2016 - 2017
January
news title 1 (January 1, 2014)
news title 2 (January 17, 2014)
February
news title 1 (February 5, 2014)
news title 2 (February 20, 2014)
As you can get an idea that first of all, i want to show all year's list(2013, 2014, 2015) and i did it successfully.
And now i want that below that list of years, the news must be displayed grouped according to months(e.g. all news of January month under "January" heading and so on till December of Year 2014 and below that, similarly complete set of all news according to months of Year 2015 and so on....)
I just want to know if there is any way to get required results from a SQL join or group by query
or i will have to manage this 100% using coding and by simply fetching all records from table without any query.
I have searched for this on google but not getting the solutions.
Need just a little idea regarding this.....

I may know nothing about CakePHP and I've been wondering why would you ever have separate tables with month and year ID's.. as I've asked in a comment which you didn't mind replying.
Anyway, if you want to keep your database structure, just use this :
SELECT
news.title,
months.name,
months.day,
years.year
FROM news
JOIN months ON months.id = news.month_id
JOIN years ON years.id = news.year_id
ORDER BY
months.month ASC,
years.year ASC
I think this should do ( did not check obviously if there's any error but.. this is the idea ).
You cannot group since we're not using any aggregate function.
To note that I just assumed the columns of years and months as I have no idea how did you name your other columns from those tables aside the id which I guess it's just an index but you can replace them as you wish
Even though I suggest getting rid of your months and years tables and just store the month and year number if you really want to in the News table as you can always output a month's name in PHP.

Related

MySQL grouping by season

Im trying to figure out the most efficient way of calculating statistics using data from MySQL database with dates.
Currently, I use the following syntax
Example:
SELECT sum(Precipitation) from DataTable GROUP BY YEAR(Datetime)
This works perfectly fine, I get the total rainfall for each year. However, now I would like to implement the option to set the beginning of the rain season. In some places, the rain season might begin for example in September. In such case I would need the same calculation, i.e. also grouped by "years", but always since Sep to Aug.
I was thinking about how to do this and the only way I can think of would be somehow calculating the monthly sums and the using PHP try to add them up. But the problem is that that would probably be much slower given there is lots of data and the original script uses just this one line above.
Is there any more efficient way of then getting something like
2014 - xyz inches, 2015 - xyz inches, but where the 2014 would correspond for example to season 2014/2015 etc.
The data in the table is like this: column 1 is always the Datetime and then the actual value, data in 5 minute intervals. I need to maintain the table structure, so I cannot create a different table where the values would be organized differently.
Use this query:
SELECT SUM(Precipitation)
FROM DataTable
GROUP BY YEAR(DATE_SUB(Datetime, INTERVAL 8 MONTH))
This query shifts every date backwards by 8 months, with the result that September 1, 2016 would appear to be the first day of 2016, and August, 2016, would appear to be the last month of 2015.

Best way to count and group blog-like results

We have a database of news posts on our site that has some 3000 rows (one for each post, dating back to 2001). Each has a unix timestamp indicating it's post date.
I want to have an archive page that shows a summary of how many posts were on that given month. So grouped by year, then month
2011
January (13 posts)
February (25 posts)
2012
March (30 posts)
etc.
What's the most efficient way of doing this? I had a mess of code before that had two for loops (year, then month) which would query the database for each month and count how many posts were made then. It was, not surprisingly, incredibly slow.
Any tips on how to group the data and avoid hitting the database for every single month.
This is best handled with a aggregated table in the database for keeping statistics on a monthly basis. You can have a simple table with 3 columns.
Year | Month | Count
on a daily basis you run a simple aggregated query counting the number of posts for that month (using a filter) and update the table above. It will be fast and clean.

PHP MYSQL Blog Archive Menu by Year and Month

I'm looking for an efficient way to collate all blog posts into a menu of the following format:
2012
August(6)
September(4)
October(2)
Month representing the month(obviously), and the value inside the brackets representing the number of posts in that month. Once clicked, a search will then be made for all posts in that month, in that year.
I need it to be dynamic, picking up November automatically when a post is created in that month, and carrying on into December, into 2013 etc etc...
All I have is a UNIX timestamp for each post. I would really like to avoid using seperate functions to gather endless comlex arrays etc.
Any help much appreciated.
From your question, I understand you're trying to come up with a query to group a number of elements by month and year. The following should do the trick:
SELECT
YEAR(dateField) AS YEAR,
MONTH(dateField) AS MONTH,
COUNT(*) AS TOTAL
FROM table
GROUP BY YEAR, MONTH
Obviously, "dateField" being the name of your datetime/timestamp column and "table" being the name of your table.
More information on the GROUP BY clause and aggregate functions (such as the COUNT(*) function used above) here.

how to count the number of dates in a table

I have a small custom blog type site and I keep track of my posts with a datetime field in the DB that hold a current_timestamp when entered.
I am working on a pagination setup and want to figure out how many unique days there are in my DB.
For example in the below screen shot there are 19 entries but only entered on 5 different days.
I want to be able to find the number of unique days in the DB. In the above shot 5.
This way I can paginate my posts by groups of days, say 7 but still show all the posts for all those days regardless of if one day has more posts or one day has none.
EX for page 1 showing the first 7 days of posts:
Jan 1st
+post
+post
+post
Jan 3
+post
Jan 4
+post
+post
Jan 5
+post
Jan 6
+post
+post
Jan 7
+post
Jan 8
+post
+post
How is the best way to get this data or paginate in this way?
Thanks
Try below:
select count(*),date from tablename group by left(date,10)
above query will give count of unique days.
This will give you the amount of posts per day:
select from_days(to_days(date)) day, count(*) from t
group by day
You can then apply a limit to the amount of records (days) to paginate them per 7 days:
select from_days(to_days(date)) day, count(*) from t
group by day
limit 7
Now, if you want to get the actual posts (I think that is what you want), you can do this:
select date, file from t t1 join (
select to_days(date) day from t
group by day
order by day desc
limit 7
) t2
on to_days(t1.date) = t2.day
This will give you all posts for the 7 most current days. Is that what you where looking for?
Edit:
I may be misinterpreting or did not ask my question well but I want the the count of all total unique days not posts. - ian
LOL: That's easier :)
select count(distinct to_days(date)) from t
I guess what you are looking for is
SELECT count(*) from table group by DATE(date)
the trick is to map datetime into date via DATE() function
UPDATE: sorry I missinterpreted your question. This will return the number of posts in each day.
To get number list of unique days you could do
SELECT DISTINCT DATE(datetime) from table
To get number of unique days you could either check the count of it in your back-end language or make a subquery, like:
select count(*) from (select distinct date(datetime) from table) as res

Archive Builder PHP

Before i start id like to say ive posted this question as more of a discussion rather than Problem Question.
In my Database i have news posts lets say with 3 columns (Id, title, date). Wher Id and title are self Explanitory the date is stored in mktime() values, in other words the number of seconds passed since 1 January 1970.
Now what i want to do is build an archive link that will display as such
July 2009
June 2009
March 2009
Feburary 2009
December 2008
Note the months on which there were no posts are not displayed.
Now as an initial thought i was thinking
Start with the last day of the current Month
And get the Value of the First day of the current Month
Do a MySQL COUNT Query/mysql_num_rows for posts that were date >= First_Day_Seconds AND date <= Last_Day_Seconds
Display or put the values in an Array
Do another Query to Check if Any more values are found WHERE date < First_Day_Seconds (break if no rows were found)
Now the above is just something on the top of my head. But if you got any ideas to speed this process up please share.
Will say in advance, date needs to be in mktime format
I would suggest using a database "native" time format, but it works with UNIX timestamps as well.
You can simply do:
SELECT DISTINCT FROM_UNIXTIME(date, '%M %Y') FROM posts;
Optionally with a WHERE clause limiting the dates to past or future dates. Possibly an ORDER clause thrown in for good measure. That should be pretty much all that's needed, let the database do as much work as possible.
If you need more formatting options, select the dates with "%Y-%m" instead and format them in PHP:
date($myCustomFormat, strtotime("$date-01"));
You can use this query to get years
"SELECT *,content_id,COUNT(content_id) AS itemCount FROM content_mast GROUP BY DATE_FORMAT(date_upload,'%Y') DESC";
now use can use this query to get month of that year
$tday = date("Y", $datetime);
$s1="select * from content_mast where DATE_FORMAT(date_upload,'%Y')=$tday";

Categories