MySQL Select Newest Approval Date among article date & comment date - mysql

My aim is to write the last modified date (lastmod) of my approved articles for my sitemap.xml file. There are 2 possibilities for this data.
If article has no approved comment, then lastmod is the approval
date of the article.
If article has at least 1 approved comment, then lastmod is the
approval date of the last approved comment of related article.
after asking php unsuccessful while loop within prepared statements question and reading answers, I decided
not to use loop within prepared for this case
add col_article_id column to my comments table which shows the
related article's id in article table
and try to solve my case with a smarter mySQL query
I have 2 tables:
articles
comments (comments.col_article_id links the comment to the related
article)
After I tried query below,
select tb_articles.col_approvaldate, tb_comments.col_approvaldate
from tb_articles, tb_comments
where tb_articles.col_status ='approved' AND tb_comments.col_status ='approved' AND tb_articles.col_id=tb_comments.col_article_id
my problems are:
1 - I need someway as if it was allowed in mysql syntax that select max( tb_articles.col_approvaldate, tb_comments.col_approvaldate)
2 - If I have n approved articles without any approved comment and m approved articles with approved comment(s), then I should have n+m result rows with 1 column at each row. But currently, I have m rows with 2 columns at each row.
So I'm aware that I'm terribly on wrong way.
I also searched "mysql newest row per group" keywords. But this the point I could arrived after all.
this is my 1st join experience. can you please correct me? best regards

Try this:
select
tb_articles.id,
ifnull(
max( tb_comments.col_approvaldate),
tb_articles.col_approvaldate
) as last_approved
from tb_articles
left join tb_comments
on tb_articles.col_id=tb_comments.col_article_id
and tb_comments.col_status ='approved'
where tb_articles.col_status ='approved'
group by 1;

Do I understand correctly that tb_comments record for an article is created by default? This should not be the case - if there are no comments, there shouldn't be a record there. If there is, what is the default date you are putting in? NULL? Also tb_comments.col_status seems redundant to me - if you have tb_comments.col_approvaldate then it is approved on that date and you don't really need status at all.
This query is probably what would work for you (commented AND shouldn't change things if I understand your table structure properly):
SELECT
a.col_id AS 'article_id',
IFNULL(MAX(c.col_approvaldate), a.col_approvaldate)
FROM
tb_articles a
LEFT JOIN tb_comments c ON a.col_id = c.col_article_id #AND c.col_status ='approved'
WHERE
a.col_status ='approved'
GROUP BY a.col_id

Related

How to make a selection of posts from the database with the condition?

How to choose the posts from the database with the condition. Already 2 days of head scratching do not understand how to win the query) I have 3 tables:
I need to choose the posts as shown on the picture:
I get to make a selection of all positions whose pivot based table has a status of checked without conditions. But you must choose the post as shown in the picture, for example a post with id 39 if his column cheked status is checked in all rows. This means that all users have approved the post and it should show. Please tell me how to do such a condition in the query?
SELECT p.*
FROM posts p
WHERE NOT EXISTS( SELECT 'a'
FROM post_user pu
WHERE pu.post_id = p.id
AND pu.checked = 'notChecked'
)

MySQL joined query with max dates from two tables

I got two tables that contain date and time stamps and trying to extract records by the latest date in both.
Table 1 (sessions):
id---login_date------------ip
01---2014-01-02 23:58:40---127.0.0.1
03---2014-01-01 13:20:16---127.0.0.1
01---2014-01-01 17:06:15---127.0.0.1
02---2013-12-30 14:34:39---127.0.0.1
*also multiple other non-date columns which are not playing part in this solution
Table 2 (reminders):
id---last_reminder---------next_reminder
03---2013-12-29 22:50:18---2014-01-07 22:50:18
02---2014-01-01 15:15:15---2014-01-09 15:15:15
02---2013-11-16 08:54:23---2013-11-23 08:54:23
Now this is the way I get all the latest logins from the first table for each user ID:
SELECT a.id, a.login_date
FROM sessions a
WHERE a.login_date = (
SELECT max(login_date) as login_date
FROM sessions
WHERE id = a.id
LIMIT 1
)
GROUP BY a.id
What I would like to get is not only the last login date for each user ID, but also the last sent reminder (if any). As this involves selecting two max dates I never get correct results.
Desired Result:
id---login_date------------last_reminder---------next_reminder------
01---2014-01-02 23:58:40---NULL------------------NULL---------------
02---2013-12-30 14:34:39---2014-01-01 15:15:15---2014-01-09 15:15:15
03---2014-01-01 13:20:16---2013-12-29 22:50:18---2014-01-07 22:50:18
Would anybody please help me out with this.
Thanks,
Simon
////////////////////////UPDATED 2014-01-04 WITH EXTRA COLUMNS////////////////////////////
Based on the request the above table structure was updated to contain extra fields, required to produce correct query results.
*note that next_reminder field will always have a value as it's calculated based on the last reminder value. The query will eventually check whether the next reminder is within certain timeframe too.
P.S. StackOverflow is full of very good answers when only one table contains the date and time stamp (from which I have built what I have got so far), however I could not locate any similar examples that would involve joining two tables and selecting max dates from each.
if you have only two columns per table, you can directly join it and use MAX() to get the latest record for each ID.
SELECT a.id,
MAX(login_date) latest_login_date,
MAX(last_reminder) latest_reminder
FROM sessions a
LEFT JOIN reminders b
ON a.id = b.id
GROUP BY a.id
SQLFiddle Demo

SQL Code to order by data from related table

Okay this SQL query is giving me a headache, hoping theres someone who's done something like this before.
I have two tables (truncated)
tblTickets: tblNotes:
ticketno (int) noteid (int)
firmid (int) ticketno (int)
ticket_desc (text) datecreated (datetime)
... ...
They are related in that a Ticket can have many Notes
What I need to do is create a query that searches by firmid (i.e. 32) and orders the "Tickets" by their latest "Note" using tblNotes.datecreated (ordered newest first)
Thanks!
NB. MySQL server (5.5.32)
EDIT: To those who've marked the question down: I have tried, and the furthest successful SQL I got was to list all tickets and notes joined by using JOIN on ticketno, I didnt add this code to the question because I guessed I was going about it all the wrong way, and maybe I needed to use a UNION, something I've always found tricky to use.
I need it to only search by the latest note for each ticket. Thats what I needed help on.
You need to use a sub-query within the WHERE clause of your SQL to identify the last note date and then join to the SQ to limit the notes that are returned.
The following should be enought to get you started.
SELECT ...
FROM tblTickets T
INNER JOIN
tblNotes N
ON N.ticketno = T.ticketno
INNER JOIN
(SELECT N1.ticketno
,MAX(N1.datecreated) AS last_note_date
FROM tblNotes N1
GROUP BY
N1.ticketno
)SQ
ON N.ticketno = SQ.ticketno
AND N.datecreated = SQ.last_note_date

Mysql - Ordering Facebook posts, comments, and replies correctly

Can't seem to find a good answer for this. I currently have two tables, one with Facebook posts, the other with comments. I now need to add replies in addition to this, since FB recently did this.
My current query selects from the posts and joins to the comments. What I'm hoping to do for the replies is to add another entry in the comments but with a parent ID. Whatever query I end up having, I would like the results to look like this:
postID commentID parentID
1
2 1
2 2 1
2 3 1
3 4
So post 1 has no comments, post 2 has one comment with two replies to that comment, and post 3 only has one comment. In my comments table, comment 1-4 are all separate entries in the same table. Is there anyway to do this with one query and not having to have another join to the comments table?
Edit, current query. This query doesn't take care of replies, it's only for posts and one level of comments.
select facebookFeeds.*, facebookComments.userID, facebookComments.name, facebookComments.message as cMessage, facebookComments.createdTime as cCreatedTime from facebookFeeds left join facebookComments on facebookFeeds.id = facebookComments.feedID where facebookComments.accountID= 24 order by createdTime desc
I figured it out, have it working using an if in the order clause. The only disadvantage is that the parent comment ID must be a lower number than its replies. Otherwise, the replies will show before the parent comment. When receiving the data, the replies come after the comment, so it should be fine.
select facebookFeeds.*, facebookComments.id as cID, parentID, facebookComments.userID, facebookComments.name, facebookComments.message as cMessage, facebookComments.createdTime as cCreatedTime from facebookFeeds left join facebookComments on facebookFeeds.id = facebookComments.feedID where facebookComments.accountID = 24 order by facebookFeeds.createdTime desc, if(parentID is null, cID, parentID)

MySQL Sort Query

I have a (what I am hoping to be easy) problem with a MySQL query.
I have 2 tables: articles, comments
An article can have many comments so there is a foreign of article_id in the comments table.
I want to get all the articles and while loop them to show on the page and then get all the comments count for each article. Easy, this is done. Now the problem is I want to sort the results based on number of comments but still show the results in the same way.
So basically I want to:
SELECT *
FROM tbl_articles
JOIN tbl_comments
ORDER BY (the most comments);
I am hoping this can all be done in a single query as the entire query is build dynamically from multiple sets of checkboxes where a single query could look like:
SELECT *
FROM tbl_articles
WHERE subject IN (1,2,5)
AND medium IN (1,3)
AND date_active > NOW()
AND...
Any further information I am happy to provide.
Something like...
SELECT *, COUNT(tbl_comments.id) as comments_count
FROM tbl_articles JOIN tbl_comments ON (tbl_comments.article_id = tbl_articles.id)
GROUP BY tbl_comments.article_id
ORDER BY comments_count;