我正在尝试执行一个SQL查询,该查询将获得不同表中的行总和,其中uuid
列与post
列中的type
列相匹配,并附加值到结果的行。 type
表中的列votes
的值分别为0和1,0表示从总和开始的-1,1表示+1到总分的和。完成所有这些操作后,我希望对score
列中的结果进行排序,以使其得分最高。
如果您想使用SQL小提琴,请访问以下链接:http://sqlfiddle.com/#!9/cc490b/1/0
posts
表的表架构的简化版本是:
uuid varchar(256)
contents text
author varchar(256)
comment varchar(256)
timestamp varchar(256)
removed varchar(256)
votes
表的架构为:
user varchar(256)
post varchar(256)
type int(1)
由于这是查询的一部分,所以这是follows
表的架构:
user varchar(256)
target varchar(256)
我当前用于获取帖子提要的查询如下,我希望以此为基础:
SELECT *
FROM posts
WHERE timestamp <= ?
AND removed IS NULL
AND comment IS NULL
AND author IN (SELECT target
FROM follows
WHERE user = ?
UNION
SELECT ? AS target)
ORDER
BY timestamp DESC
LIMIT 25;
我期望查询的最终结果如下:
| uuid | contents | author | comment | timestamp | removed | score (DESC) |
| p12c | Hi! | u7h34 | NULL | 1560269397 | NULL | 451 |
| p100 | Chicken | u211f | NULL | 1560269417 | NULL | 14 |
DDL:
DROP TABLE IF EXISTS `follows`;
DROP TABLE IF EXISTS `votes`;
DROP TABLE IF EXISTS `posts`;
CREATE TABLE `follows` (
`user` varchar(256) NOT NULL,
`target` varchar(256) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `follows` (`user`, `target`) VALUES
('user-uuid2', 'user-uuid1');
CREATE TABLE `votes` (
`user` varchar(256) NOT NULL,
`post` varchar(256) NOT NULL,
`type` int(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `votes` (`user`, `post`, `type`) VALUES
('user-uuid2', 'post-uuid9', 0),
('user-uuid2', 'post-uuid9', 1),
('user-uuid2', 'post-uuid8', 1);
CREATE TABLE `posts` (
`uuid` varchar(256) NOT NULL,
`contents` text NOT NULL,
`author` varchar(256) NOT NULL,
`comment` varchar(256) DEFAULT NULL,
`timestamp` varchar(256) NOT NULL,
`removed` varchar(256) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `posts` (`uuid`, `contents`, `author`, `comment`, `timestamp`, `removed`) VALUES
('post-uuid1', 'Hello world1!', 'user-uuid1', NULL, '1560184505', NULL),
('post-uuid2', 'Hello world2!', 'user-uuid1', NULL, '1560184506', NULL),
('post-uuid3', 'Hello world3!', 'user-uuid1', NULL, '1560184507', NULL),
('post-uuid4', 'Hello world4!', 'user-uuid1', NULL, '1560184508', NULL),
('post-uuid5', 'Hello world5!', 'user-uuid1', NULL, '1560184509', NULL),
('post-uuid6', 'Hello world6!', 'user-uuid1', NULL, '1560184510', NULL),
('post-uuid7', 'Hello world7!', 'user-uuid1', NULL, '1560184511', NULL),
('post-uuid8', 'Hello world8!', 'user-uuid1', NULL, '1560184512', NULL),
('post-uuid9', 'Hello world9!', 'user-uuid1', NULL, '1560184513', NULL),
('post-uuid10', 'Hello world10!', 'user-uuid1', NULL, '1560184514', NULL),
('post-uuid11', 'Hello world11!', 'user-uuid1', NULL, '1560184515', NULL),
('post-uuid12', 'Hello world12!', 'user-uuid1', NULL, '1560184516', NULL);
答案 0 :(得分:1)
除非我缺少任何内容,否则我认为您只需要SUM
表达式的CASE
。
(我不得不注释WHERE
子句,因为它删除了带表决权的帖子。)
SELECT
p.uuid,
p.contents,
p.author,
p.comment,
p.timestamp,
p.removed,
SUM(COALESCE(CASE WHEN v.type = 0 THEN -1 ELSE v.type END,0)) as Score
FROM posts p
LEFT JOIN votes v
ON v.post = p.uuid
-- WHERE timestamp <= '1560184509'
AND removed IS NULL
AND comment IS NULL
AND author IN (SELECT target
FROM follows
WHERE user = '2452be00-5b48-4c09-8abb-21d469bc8e11'
UNION
SELECT '2452be00-5b48-4c09-8abb-21d469bc8e11' AS target)
GROUP BY
p.uuid,
p.contents,
p.author,
p.comment,
p.timestamp,
p.removed
ORDER
BY Score DESC
LIMIT 25;
您的小提琴回到您身边:http://sqlfiddle.com/#!9/61068/8/0