【发布时间】:2020-07-07 04:21:10
【问题描述】:
上下文
我正在尝试在我的网站上创建一个“提要”系统,用户可以在其中访问他们的提要并查看他们在网站上可以执行的不同操作的所有新通知。例如,在“feed”部分,用户可以查看他们关注的用户是否创建了文章,以及用户是否对文章发表了评论。我当前的提要系统仅使用两个单独的查询来获取此信息。但是,我想将这两个查询合并为一个,以便用户可以按时间顺序查看他们关注的人的活动。我的系统现在的工作方式是,我从用户关注的每个人那里获取五篇文章并将其放在“提要”部分,然后获取五篇文章 cmets 并将其发布在“提要”部分的同一区域中。我不想将查询分开,而是将它们组合起来,这样,他们将看到按时间顺序发生的提要帖子,而不是连续看到五个文章帖子,然后连续看到五个文章 cmets,而不管其他用户是否创建首先是一篇文章,然后发表评论,然后创建另一篇文章,或者以任何顺序,而不是总是看到相同的通知顺序。
问题
首先,如果您想重新创建表格,让我向您展示我的表格创建代码。首先要做的是创建一个users 表,我的articles 和articlecomments 表引用了它:
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;
接下来,让我们创建articles 表:
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;
最后,我们需要articlecomments 表:
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;
为了在本示例中充分填充表格,我们将使用以下语句:
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');
我用来从articles 和articlecomments 表中获取数据的两个查询如下:
查询 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
查询 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
如何组合这两个包含不同信息和列的查询,以便根据创建日期(分别为articles.date 和articlecomments.date)对它们进行排序?我希望它们在不同的行中,而不是在同一行中。因此,应该就像我分别查询它们并将结果行简单地组合在一起一样。如果有 3 篇文章和 3 篇文章 cmets,我希望总共返回 6 行。
这就是我想要的样子。鉴于有三篇文章和三篇文章 cmets,并且 cmets 是在文章之后创建的,这就是结合上述查询后的结果应该是什么样子(我不确定在不同的列名下是否可以这样描述,但我'想知道是否可以完成类似的事情):
+-------------------------------+-------------------+---------------------+----------------------------------------------------------------+---------+-------------+
| 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 |
+-------------------------------+-------------------+---------------------+----------------------------------------------------------------+---------+-------------+
我尝试过的事情
我读到这可能涉及JOIN 或UNION 运算符,但我不确定如何在这种情况下实现它们。我确实尝试通过简单地使用(Query 1) UNION (Query 2) 来组合这两个查询,它起初告诉我,我的两个查询中的列数不同,所以我不得不从我的articlecomments 查询中删除idUsers 列。这实际上让我有点接近,但它的格式不正确:
+------------+-------------------+---------------------+---------+-------------+
| 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 |
+------------+-------------------+---------------------+---------+-------------+
有什么想法吗?让我知道是否有任何混淆。谢谢。
Server type: MariaDB
Server version: 10.4.8-MariaDB - mariadb.org binary distribution
【问题讨论】:
-
首先,您需要想象这种“组合操作”的最终结果应该是什么样子 - 并记录该愿景(只需准备一份规范)。您正在尝试组合两个查询,但您不太确定要获得什么。我投票结束这个问题。
-
从您的大部分描述来看,
UNION应该是正确的答案,因此如果您可以在问题中添加一些示例数据和预期结果,这将有助于极大地很清楚你们都想以何种方式“组合查询”并拥有“单独的行”,这听起来像是相互矛盾的。 -
请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入作为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 在给出业务关系(船舶)/关联或表(基本或查询结果)时,说明其中的一行根据其列值说明了业务情况。当卡住时,您可以编写代码并说出他们的工作并解释卡住的情况。
-
感谢您的反馈。我只是把它变成了一个可重复的答案。你能再看看吗?
-
“在给出业务关系(船舶)/关联或表(基本或查询结果)时,说明其中的一行根据其列值说明了业务情况。”我在这里有一行值,(id、tm、date、article_id、idUsers、uidUsers)& 我有一些表用户、文章和 articlecmets 的值。我的行在什么条件下进入结果? PS问1个问题。不要写关于你想知道的事情的其他问题,因为这样就不清楚你的帖子在问什么。如果您想问其他(特定研究的非重复)问题,请发布另一个帖子。
标签: sql join union mariadb-10.4