共計(jì) 3108 個(gè)字符,預(yù)計(jì)需要花費(fèi) 8 分鐘才能閱讀完成。
這篇文章主要介紹了 SQL 如何求時(shí)間差之和,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓丸趣 TV 小編帶著大家一起了解一下。
題目如下:
求每個(gè)品牌的促銷天數(shù)
表 sale 為促銷營(yíng)銷表,數(shù)據(jù)中存在日期重復(fù)的情況,例如 id 為 1 的 end_date 為 20180905,id 為 2 的 start_date 為 20180903,即 id 為 1 和 id 為 2 的存在重復(fù)的銷售日期,求出每個(gè)品牌的促銷天數(shù) (重復(fù)不算)
表結(jié)果如下:
+------+-------+------------+------------+
| 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 |
+------+-------+------------+------------+
最終結(jié)果應(yīng)為
brandall_daysnike13oppo12vivo18
建表語(yǔ)句
-- ----------------------------
-- 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:
利用自關(guān)聯(lián)下一條記錄的方法
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
運(yùn)行結(jié)果
+-------+---------+
| brand | all_day |
+-------+---------+
| nike | 13 |
| oppo | 12 |
| vivo | 18 |
+-------+---------+
該方法對(duì)本題中的表格有效,但對(duì)于有 id 不連續(xù)的品牌的記錄時(shí)不一定適用。
方式 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
運(yùn)行結(jié)果
+-------+----------+
| 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)
結(jié)果同樣正確
用分析函數(shù)同樣可行的,自己電腦暫時(shí)沒(méi)裝 oracle,用的 mysql 寫的。
感謝你能夠認(rèn)真閱讀完這篇文章,希望丸趣 TV 小編分享的“SQL 如何求時(shí)間差之和”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持丸趣 TV,關(guān)注丸趣 TV 行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!