加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

SQL怎样求时间差之和

发布时间:2022-02-09 16:14:55 所属栏目:MySql教程 来源:互联网
导读:这篇文章主要介绍了SQL如何求时间差之和,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 题目如下: 求每个品牌的促销天数 表sale为促销营销表,数据中存在日期重复的情况,例如id为1的
SQL怎样求时间差之和
       这篇文章主要介绍了SQL如何求时间差之和,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
 
题目如下:
 
求每个品牌的促销天数
 
       表sale为促销营销表,数据中存在日期重复的情况,例如id为1的end_date为20180905,id为2的start_date为20180903,即id为1和id为2的存在重复的销售日期,求出每个品牌的促销天数(重复不算)
 
表结果如下:
 
+------+-------+------------+------------+
| id | brand | start_date | end_date |
+------+-------+------------+------------+
| 1 | nike | 2018-09-01 | 2018-09-05 |
| 2 | nike | 2018-09-03 | 2018-09-06 |
| 3 | nike | 2018-09-09 | 2018-09-15 |
| 4 | oppo | 2018-08-04 | 2018-08-05 |
| 5 | oppo | 2018-08-04 | 2018-08-15 |
| 6 | vivo | 2018-08-15 | 2018-08-21 |
| 7 | vivo | 2018-09-02 | 2018-09-12 |
+------+-------+------------+------------+
最终结果应为
 
brand all_days
nike 13
oppo 12
vivo 18
建表语句
 
-- ----------------------------
-- Table structure for sale
-- ----------------------------
DROP TABLE IF EXISTS `sale`;
CREATE TABLE `sale` (
 `id` int(11) DEFAULT NULL,
 `brand` varchar(255) DEFAULT NULL,
 `start_date` date DEFAULT NULL,
 `end_date` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of sale
-- ----------------------------
INSERT INTO `sale` VALUES (1, 'nike', '2018-09-01', '2018-09-05');
INSERT INTO `sale` VALUES (2, 'nike', '2018-09-03', '2018-09-06');
INSERT INTO `sale` VALUES (3, 'nike', '2018-09-09', '2018-09-15');
INSERT INTO `sale` VALUES (4, 'oppo', '2018-08-04', '2018-08-05');
INSERT INTO `sale` VALUES (5, 'oppo', '2018-08-04', '2018-08-15');
INSERT INTO `sale` VALUES (6, 'vivo', '2018-08-15', '2018-08-21');
INSERT INTO `sale` VALUES (7, 'vivo', '2018-09-02', '2018-09-12');
方式1:
 
利用自关联下一条记录的方法
 
select brand,sum(end_date-befor_date+1) all_days from
 (
 select s.id ,
  s.brand ,
  s.start_date ,
  s.end_date ,
  if(s.start_date>=ifnull(t.end_date,s.start_date) ,s.start_date,DATE_ADD(t.end_date,interval 1 day) ) as befor_date
 from sale s left join (select id+1 as id ,brand,end_date from sale) t on s.id = t.id and s.brand = t.brand
 order by s.id
 )tmp
 group by brand
运行结果
 
+-------+---------+
| brand | all_day |
+-------+---------+
| nike |  13 |
| oppo |  12 |
| vivo |  18 |
+-------+---------+
该方法对本题中的表格有效,但对于有id不连续的品牌的记录时不一定适用。
 
方式2:
 
SELECT a.brand,SUM(
 CASE
  WHEN a.start_date=b.start_date AND a.end_date=b.end_date
  AND NOT EXISTS(
  SELECT *
  FROM sale c LEFT JOIN sale d ON c.brand=d.brand
   WHERE d.brand=a.brand
   AND c.start_date=a.start_date
   AND c.id<>d.id
   AND (d.start_date BETWEEN c.start_date AND c.end_date AND d.end_date>c.end_date
   OR
  c.start_date BETWEEN d.start_date AND d.end_date AND c.end_date>d.end_date)
    )
   THEN (a.end_date-a.start_date+1)
  WHEN (a.id<>b.id AND b.start_date BETWEEN a.start_date AND a.end_date AND b.end_date>a.end_date ) THEN (b.end_date-a.start_date+1)
  ELSE 0 END
  ) AS all_days
FROM sale a JOIN sale b ON a.brand=b.brand GROUP BY a.brand
运行结果
 
+-------+----------+
| brand | all_days |
+-------+----------+
| nike |  13 |
| oppo |  12 |
| vivo |  18 |
+-------+----------+
其中条件
 
d.start_date BETWEEN c.start_date AND c.end_date AND d.end_date>c.end_date
   OR
c.start_date BETWEEN d.start_date AND d.end_date AND c.end_date>d.end_date
可以换成
 
c.start_date < d.end_date AND (c.end_date > d.start_date)
结果同样正确
 
用分析函数同样可行的,自己电脑暂时没装oracle,用的mysql写的。
 
感谢你能够认真阅读完这篇文章,希望小编分享的“SQL如何求时间差之和”这篇文章对大家有帮助。

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!