在三个表中计算三个差总和

时间:2019-05-25 23:04:39

标签: mysql group-by sum subquery

我有这些表:

DROP TABLE IF EXISTS books;
CREATE TABLE `books` (
  `bookId` mediumint(8) UNSIGNED NOT NULL,
  `title` varchar(10) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `books`
  ADD PRIMARY KEY (`bookId`),

DROP TABLE IF EXISTS movements;
CREATE TABLE `movements` (
  `movementId` mediumint(8) UNSIGNED NOT NULL,
  `movementTypeId` tinyint(3) UNSIGNED NOT NULL,
  `deletedFlag` tinyint(3) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `movements`
  ADD PRIMARY KEY (`movementId`),
  ADD KEY `movementId` (`movementTypeId`,`deletedFlag`) USING BTREE;

DROP TABLE IF EXISTS movements_types;
CREATE TABLE `movements_types` (
  `movementTypeId` mediumint(8) UNSIGNED NOT NULL,
  `title` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `movements_types`
  ADD PRIMARY KEY (`movementTypeId`);

DROP TABLE IF EXISTS movements_books;
CREATE TABLE `movements_books` (
  `movementId` mediumint(8) UNSIGNED NOT NULL,
  `bookId` mediumint(8) UNSIGNED NOT NULL,
  `bookSize` tinyint(3) UNSIGNED NOT NULL,
  `quantity` smallint(5) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `books` (`bookId`, `title`) VALUES
(1, 'Harry Potter'),
(2, 'Mysql Join'),
(3, 'Comedy');

INSERT INTO `movements` (`movementId`, `movementTypeId`, `deletedFlag`) VALUES
(7, 1, 0),
(8, 2, 0),
(9, 2, 0);

INSERT INTO `movements_types` (`movementTypeId`, `title`) VALUES
(1, "Bought"),
(2, "Sold");

INSERT INTO `movements_books` (`movementId`, `bookId`, `bookSize`, `quantity`) VALUES
(7, 1, 1, 3),
(7, 1, 2, 3),
(7, 2, 1, 3),
(7, 2, 2, 3),
(8, 1, 1, 2),
(8, 1, 1, 2),
(9, 2, 1, 3);

bookSize只是表示书籍大小的整数。

movements_books实际上有111824条记录,运动有4534条记录。 对于已删除的动作,deleteFlag为1(我更希望对其进行标记),否则为0。

我需要帮助来创建索引,我需要这些结果:

1)每本书的售出/购买/可用大小(bookId,bookSize,booksSold,booksBought,booksBought减去书本已售出)

2)每本各种尺寸的书籍(bookId,booksSold,booksBought,booksBought减去书本已售出)的售出/购买/可获得的书

要获取我尝试过的统计数据之一:

SELECT 
   books.title
   movements_books_grouped.bookId,
   SUM(IF(movements.movementTypeId=1, movements_books_grouped.quantity, NULL)) AS booksBought,
   SUM(IF(movements.movementTypeId=2, movements_books_grouped.quantity, NULL)) AS booksSold,
   (
       SUM(IF(movements.movementTypeId=1, movements_books_grouped.quantity, 0))- 
       SUM(IF(movements.movementTypeId=2, movements_books_grouped.quantity, 0)) 
   ) AS booksAvailability,
   FROM 
   (
   SELECT bookId,quantity,movementId FROM movements_books GROUP BY bookId
   ) AS movements_books_grouped 
   JOIN movements ON movements.movementId=movements_books_grouped.movementId
   JOIN books ON books.bookId=movements_books_grouped.bookId
   GROUP BY movements_books_grouped.bookId
   ORDER BY book.title

但是非常慢。 编辑:我需要在示例中添加另一个表,因为那会使上一个查询真正变慢。我需要加入此表,因为我需要按标题对结果进行排序。

1 个答案:

答案 0 :(得分:0)

这是可以使用索引的查询:

SELECT m.movementId
     , m.movementTypeId
     , m.deletedFlag
     , mb.bookId
     , mb.bookSize
     , t.title
  FROM movements m
  JOIN movements_types t 
    ON t.movementTypeId = m.movementTypeId
  JOIN movements_books mb
    ON mb.movementid = m.movementid
 WHERE m.deletedFlag=0;

在(m.movementTypeId,m.deletedFlag)上的索引可能被证明是有益的,但最好是将其吸取并查看。