SQL将列添加到包含与查询匹配的其他表中的行总和的结果中

时间:2019-06-11 16:17:37

标签: mysql sql

我正在尝试执行一个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);

1 个答案:

答案 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