Context
I'm trying to create a "feed" system on my website where users can go to their feed and see all their new notifications across the different things they can do on the website. For example, in the "feed" section, users are able to see if the users they follow have created articles and if the users have commented on articles. My current feed system simply uses two separate queries to obtain this information. However, I want to combine these two queries into one so that the user can view the activity of those they follow chronologically. The way my system works now, I get five articles from each person the user follows and put it in the "feed" section and then get five article comments and post it in the same area in the "feed" section. Instead of the queries being separate, I want to combine them so that, instead of seeing five article posts in a row and then five article comments in a row, they will see the feed posts that happened in chronological order, whether the other users created an article first, then commented, then created another article, or whatever the order is, instead of always seeing the same order of notifications.
Question
First, let me show you my code for table creation if you would like to recreate this. The first thing to do is to create a users
table, which my articles
and articlecomments
tables reference:
CREATE TABLE users (
idUsers int(11) AUTO_INCREMENT PRIMARY KEY NOT NULL,
uidUsers TINYTEXT NOT NULL,
emailUsers VARCHAR(100) NOT NULL,
pwdUsers LONGTEXT NOT NULL,
created DATETIME NOT NULL,
UNIQUE (emailUsers),
FULLTEXT(uidUsers)
) ENGINE=InnoDB;
Next, let's create the articles
table:
CREATE TABLE articles (
article_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
title TEXT NOT NULL,
article TEXT NOT NULL,
date DATETIME NOT NULL,
idUsers int(11) NOT NULL,
topic VARCHAR(50) NOT NULL,
published VARCHAR(50) NOT NULL,
PRIMARY KEY (article_id),
FULLTEXT(title, article),
FOREIGN KEY (idUsers) REFERENCES users (idUsers) ON DELETE CASCADE ON UPDATE
CASCADE
) ENGINE=InnoDB;
Finally, we need the articlecomments
table:
CREATE TABLE articlecomments (
comment_id INT(11) AUTO_INCREMENT PRIMARY KEY NOT NULL,
message TEXT NOT NULL,
date DATETIME NOT NULL,
article_id INT(11) UNSIGNED NOT NULL,
idUsers INT(11) NOT NULL,
seen TINYTEXT NOT NULL,
FOREIGN KEY (article_id) REFERENCES articles (article_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (idUsers) REFERENCES users (idUsers) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
To populate the tables sufficiently for this example, we will use these statements:
INSERT INTO users (uidUsers, emailUsers, pwdUsers, created) VALUES ('genericUser', 'genericUser@hotmail.com', 'password', NOW());
INSERT INTO articles (title, article, date, idUsers, topic, published) VALUES ('first article', 'first article contents', NOW(), '1', 'other', 'yes');
INSERT INTO articles (title, article, date, idUsers, topic, published) VALUES ('second article', 'second article contents', NOW(), '1', 'other', 'yes');
INSERT INTO articles (title, article, date, idUsers, topic, published) VALUES ('third article', 'third article contents', NOW(), '1', 'other', 'yes');
INSERT INTO articlecomments (message, date, article_id, idUsers, seen) VALUES ('first message', NOW(), '1', '1', 'false');
INSERT INTO articlecomments (message, date, article_id, idUsers, seen) VALUES ('second message', NOW(), '1', '1', 'false');
INSERT INTO articlecomments (message, date, article_id, idUsers, seen) VALUES ('third message', NOW(), '1', '1', 'false');
The two queries that I'm using to obtain data from the articles
and articlecomments
tables are below:
Query 1:
SELECT
articles.article_id, articles.title, articles.date,
articles.idUsers, users.uidUsers
FROM articles
JOIN users ON articles.idUsers = users.idUsers
WHERE articles.idUsers = '1' AND articles.published = 'yes'
ORDER BY articles.date DESC
LIMIT 5
Query 2:
SELECT
articlecomments.comment_id, articlecomments.message,
articlecomments.date, articlecomments.article_id, users.uidUsers
FROM articlecomments
JOIN users ON articlecomments.idUsers = users.idUsers
WHERE articlecomments.idUsers = '1'
ORDER BY articlecomments.date DESC
LIMIT 5
How would I combine these two queries that contain different information and columns so that they are ordered based on the date of creation (articles.date
and articlecomments.date
, respectively)? I want them to be in separate rows, not the same row. So, it should be like I queried them separately and simply combined the resulting rows together. If there are three articles and three article comments, I want there to be six total returned rows.
Here's what I want this to look like. Given there are three articles and three article comments, and the comments were created after the articles, this is what the result should look like after combining the queries above (I'm not sure if this portrayal is possible given the different column names but I'm wondering if something similar could be accomplished):
+-------------------------------+-------------------+---------------------+----------------------------------------------------------------+---------+-------------+
| id (article_id or comment_id) | title/message | date | article_id (because it is referenced in articlecomments table) | idUsers | uidUsers |
+-------------------------------+-------------------+---------------------+----------------------------------------------------------------+---------+-------------+
| 1 | first message | 2020-07-07 11:27:15 | 1 | 1 | genericUser |
| 2 | second message | 2020-07-07 11:27:15 | 1 | 1 | genericUser |
| 3 | third message | 2020-07-07 11:27:15 | 1 | 1 | genericUser |
| 2 | second article | 2020-07-07 10:47:35 | 2 | 1 | genericUser |
| 3 | third article | 2020-07-07 10:47:35 | 3 | 1 | genericUser |
| 1 | first article | 2020-07-07 10:46:51 | 1 | 1 | genericUser |
+-------------------------------+-------------------+---------------------+----------------------------------------------------------------+---------+-------------+
Things I have Tried
I have read that this might involve JOIN
or UNION
operators, but I'm unsure of how to implement them in this situation. I did try combining the two queries by simply using (Query 1) UNION (Query 2)
, which at first told me that the number of columns were different in my two queries, so I had to remove the idUsers
column from my articlecomments
query. This actually got me kind of close, but it wasn't formatted correctly:
+------------+-------------------+---------------------+---------+-------------+
| article_id | title | date | idUsers | uidUsers |
+------------+-------------------+---------------------+---------+-------------+
| 2 | first message | 2020-07-07 10:47:35 | 1 | genericUser |
| 3 | third article | 2020-07-07 10:47:35 | 1 | genericUser |
| 1 | first article | 2020-07-07 10:46:51 | 1 | genericUser |
| 1 | second article | 2020-07-07 11:27:15 | 1 | genericUser |
| 2 | third article | 2020-07-07 11:27:15 | 1 | genericUser |
| 3 | first article | 2020-07-07 11:27:15 | 1 | genericUser |
+------------+-------------------+---------------------+---------+-------------+
Any ideas? Let me know if there is any confusion. Thanks.
Server type: MariaDB
Server version: 10.4.8-MariaDB - mariadb.org binary distribution