避免UNION在MySQL中使用两个几乎相同的表

gre*_*emo 2 mysql sql optimization

我不是很擅长MySQL,我打算写一个查询来计算用户发送的消息,根据它的类型和is_auto字段.

消息可以是"小文本消息"或"简报"类型.我创建了两个实体,它们之间有一些不同的字段.重要的是messages_count表中没有newsletter,它在查询中使用:

CREATE TABLE IF NOT EXISTS `small_text_message` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `messages_count` int(11) NOT NULL,
  `username` varchar(255) NOT NULL,
  `method` varchar(255) NOT NULL,
  `content` longtext,
  `sent_at` datetime DEFAULT NULL,
  `status` varchar(255) NOT NULL,
  `recipients_count` int(11) NOT NULL,
  `customers_count` int(11) NOT NULL,
  `sheduled_at` datetime DEFAULT NULL,
  `sheduled_for` datetime DEFAULT NULL,
  `is_auto` tinyint(1) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)

和:

CREATE TABLE `newsletter` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `subject` varchar(78) DEFAULT NULL,
  `content` longtext,
  `sent_at` datetime DEFAULT NULL,
  `status` varchar(255) NOT NULL,
  `recipients_count` int(11) NOT NULL,
  `customers_count` int(11) NOT NULL,
  `sheduled_at` datetime DEFAULT NULL,
  `sheduled_for` datetime DEFAULT NULL,
  `is_auto` tinyint(1) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Run Code Online (Sandbox Code Playgroud)

我最终得到了一个UNION查询.可以缩短或优化此查询,因为唯一的区别是messages_count应该始终为1 newsletter吗?

SELECT
CONCAT('sms_', IF(is_auto = 0, 'user' , 'auto')) AS subtype,
SUM(messages_count * (customers_count + recipients_count)) AS count
FROM small_text_message WHERE status <> 'pending' AND user_id = 1
GROUP BY is_auto
UNION
SELECT
CONCAT('newsletter_', IF(is_auto = 0, 'user' , 'auto')) AS subtype,
SUM(customers_count + recipients_count) AS count
FROM newsletter WHERE status <> 'pending' AND user_id = 1
GROUP BY is_auto
Run Code Online (Sandbox Code Playgroud)

spe*_*593 5

我没有看到任何简单的方法来避免UNION(或UNION ALL)操作,它将返回指定的结果集.

我建议您使用UNION ALL操作员代替UNION操作员.然后执行计划将不包括消除重复行的步骤.(您已经对每个查询执行了GROUP BY操作,并且这两个查询无法生成相同的行.)

否则,您的查询就像编写时一样正常.

(考虑这个问题总是一件好事,可能有更好的方法吗?要获得你要求的结果集,从你拥有的模式中,你的查询看起来和它一样好.)