display one article from multiple posts per month - mysql

Please help my knowledge is limited and I have been struggling with this for almost a week now.
I have a table which allows the user to post to it. I want to display each month that has a post in it e.g.
DEC
OCT
SEPT
AUG
FEB
However, if there has been multiple post in a single month, I only want that month to be displayed once, how do I do this?
So far I have created this:
$months = mysql_query("SELECT article_id, content, DATE_FORMAT(date, '%M')
AS date
FROM article
ORDER BY article_id
DESC
LIMIT 12");
while($row = mysql_fetch_array($months)){
echo "" . $row['date'] . "<br/>";
}
Each month that has a post is displayed the number of times posts have been made, obviously this is not what im after :(

Use the DISTINCT keyword:
SELECT DISTINCT MONTH(date) FROM article ...

Try this:
SELECT DISTINCT(MONTHNAME(date)) as post_month
FROM article
DISTINCT removes duplicates from the applied columns.

Related

MYSQL query select distinct month and year

I have a table with a datetime column with multiple dates in. I want to output the month and year for every row that exists only once. e.g "April 2017, April 2018, May 2018, June 2018"
I've managed to get the below working, this displays "April May June", but it needs to display April twice as it is in different years and I also want to display their respective years.
<?php $results = mysqli_query($link, 'SELECT DISTINCT MONTH(date_added) AS "Month" FROM payments') or die("Query fail: " . mysqli_error($link)); ?>
<?php foreach($results as $result) :?>
<?php $monthText = date("F", strtotime("2001-" . $result['Month'] . "-01")); ?>
<?= $monthText ?>
<?php endforeach; ?>
I've been researching for hours and not manged to find a solution that works.
You can apply the distinct keyword to a combination of fields:
SELECT DISTINCT YEAR(date_added) AS "Year", MONTH(date_added) AS "Month" FROM payments
You have to group:
SELECT MONTH(`date_added`) AS `Month`, YEAR(`date_added`) AS `Year`
FROM `payments`
GROUP BY `Month`, `Year`
With the later versions and strict rules you will not get the right response from either of the above answers as GROUP BY operates before the SELECT part of the query and hence it does not respond to aliases.
You need
SELECT DISTINCT MONTH(`date_added`) AS `Month`, YEAR(`date_added`) AS `Year`
FROM payments GROUP BY MONTH('date_added`), YEAR(`date_added`)

Sql query mistake for the weekly statistics

I am trying to make a weekly statistics for user registration. It should work for weekly. There are total of seven days in a week. I want to print the number of users who are registered every day in the week on the screen.
For example:
Number of users who registered on Monday = 38
Number of users who registered on Tuesday = 11
.... .... and this list will only list the week we were
I created a sql query like the following:
SELECT WEEKDAY(registerTime)+1, count(*)
FROM users group by WEEKDAY(registerTime)
ORDER BY WEEKDAY(registerTime)
But the outcome of this question is very different. This total shows the number of users who registered on Monday for every year .
You want to limit users to only this week so you don't get everything:
SELECT WEEKDAY(registerTime)+1, count(*)
FROM users
WHERE WEEKOFYEAR(registerTime) = WEEKOFYEAR(CURDATE())
AND YEAR(registerTime) = YEAR(CURDATE())
group by WEEKDAY(registerTime)
ORDER BY WEEKDAY(registerTime);
Basically you match the year and week of year with what you need. That should be enough.
Try like this :
SELECT datepart(week, registerTime), count(*) FROM Users GROUP BY datepart(week, registerTime)
You can also use Php code for this purpose. First make array of days and then you can get registered users for each day through that array
function today()
{
return date("Y-m-d");
}
function last_seventh_day()
{
return date("Y-m-d",strtotime("-7 days"));
}
$days = ['Saturday','Sunday','Monday','Tuesday','Wednesday','Thursday','Friday'];//Array that stores all days
foreach($days as $day)
{
$sql = "select * FROM users where day = '$day' and date_column between " .today() . "and" .last_seventh_day() ;
}
I have updated my answer. I hope this will work for you!

Select distinct but group them by 24 hours?

Alright so I'm creating articles. Everytime an user opens the article, their IP, article id and date gets saved into MySQL.
$date = time();
$sql = "INSERT INTO views(ip,article,date) VALUES(?,?,?)";
$stmt = $mysql->prepare($sql);
$stmt->bind_param('sss', $_SERVER['REMOTE_ADDR'],$_GET['id'],$date);
$stmt->execute();
Now, I want to get unique views and I know how to do this with DISTINCT. But this isn't entirely what I want to do. It will get unique views of all time, but I want each user's view to count for every 24 hours.
Say I'm person A and there's person B. We both view the article. Total unique views will be 2. Tomorrow I view the article again, it'll still show 2 views, but I want it to show 3 views because it has been 24 hours.
I can do this by checking if they have viewed the article therefore not adding their view count to the database, but I don't want to do this. I need an alternative way.
Thank you.
You need a GROUP BY with COUNT, but if the date is of data type datetime, then you need to group by the date part only, like this:
SELECT CAST(date AS DATE) AS Date, article, COUNT(DISTINCT ip) AS TotalViews
FROM views
WHERE article = $articleId
AND DATE>= now() - INTERVAL 1 DAY
GROUP BY CAST(date AS DATE), article
LIMIT 0, 25;
I want each user's view to count for every 24 hours.
Just use two arguments to count(distinct):
select article, count(distinct ip, date(date))
from v
group by article;
If you want a separate result for each day, then put the date logic in the group by:
select article, date(date), count(distinct ip)
from v
group by article, date(date);
However, that doesn't seem to be the question you are asking.

Group records by both month and year in Rails

I'm on Ruby 1.9.2, Rails 3.0.x and I use MySQL DB. I have a Messages Model, where one can post new messages every day.
I have an index action where I want to display these messages grouped by both month and year. This basically is used to filter messages.
My query looks like this:-
#active_msgs = Messages.where('expiry > ?', Time.now).order('created_at DESC')
I used the group_by function in Rails, after referring to this post
My Group By Query is:-
#msgs_by_month = #active_msgs.all.group_by {|u| u.created_at.month }
I was returned a Hash called #msgs_by_month. This helped me group the messages by month, but I need to taken into account the year, to form a unique key , as it would help me differentiate between for e.g., Sept 2011 and Sept 2012.
My current key only is of type Hash[Month] ( e.g. Hash[9] => for month of September, I can display all appropriate values ). How can i get a unique key of type month, year which I can easily loop though to display all records grouped by Month and Year of creation.
Thank you
EDIT:-
I'm guessing one way to do this, is to make use the created_at.to_date api, provided here
. I only wonder, how I can strip out the day from created_at.to_date to get a unique month and year combination key which could work with the group_by function.
In SQL:
select * from messages group by year(created_at), month(created_at);
In Rails:
Message.all.group_by { |m| m.created_at.beginning_of_month }
Use Group Date.
It supports time zones, so if you ever need to - the code will easily evolve.
https://github.com/ankane/groupdate
Message.select("date_trunc('month', created_at) as month").group("month")
To group by year and by month (e.g. not having december 2020 with december 2021):
Message.group("date_trunc('year', created_at), date_trunc('month', created_at)")
Tested on PostgreSQL
ModelName.all.group_by { |m| m.created_at.month }
This will work, however month will be returned as the index.
Ex. Nov would refer to 11

mySQL Query to list number of comments my site received each day?

I run an online magazine and would like a dead-simple way to track 3 metrics:
How many comments are left each day.
How many links my users submit.
How many new members I get each day.
This information is all my database, I'm just not sure how to get it out.
I have a "comments" table with about 3500 comments. Each comment gets a row in the table. One of the columns in the table is "timestamp."
I'm assuming there's a query that will select this table, sort the rows by timestamp, group them in 24-hour increments and then count the number of rows in each group - telling me how many new comments I received each day.
What would that query look like? I think I can figure out the other ones if I had the first one working.
This fragment will display your results in a themed table:
$sq = 'SELECT COUNT(*) cnt, DATE(FROM_UNIXTIME(timestamp)) day '
. 'FROM {comments} c '
. 'GROUP BY 2 '
. 'ORDER BY 2 DESC';
$q = db_query($sq);
$stats = array();
while ($o = db_fetch_object($q)) {
$stats[$o->day] = array($o->day, $o->cnt);
}
return theme('table', NULL, $stats));
Using DATE(timestamp) doesn't work because comments.timestamp is in UNIX_TIMESTAMP format, whereas DATE() expects an ASCII date.
Use the date_format() function to format the dates;
select count(id) as commentCount, date_format(dateColumn, '%Y-%m-%d') as commentDate
from yourTable
group by commentDate