国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

SQL面試題:求時(shí)間差之和(有重復(fù)不計(jì))

2020-01-18 20:39:30
字體:
供稿:網(wǎng)友

面試某某公司BI崗位的時(shí)候,面試題中的一道sql題,咋看一下很簡單,寫的時(shí)候發(fā)現(xiàn)自己缺乏總結(jié),沒有很快的寫出來。

題目如下:

求每個(gè)品牌的促銷天數(shù)

表sale為促銷營銷表,數(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)為

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:

利用自關(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í)沒裝oracle,用的mysql寫的。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 荆州市| 深水埗区| 东乡县| 侯马市| 淳化县| 西峡县| 大厂| 盐津县| 鄂托克前旗| 涿鹿县| 定州市| 蕲春县| 兴仁县| 中卫市| 广南县| 许昌市| 安丘市| 文登市| 临颍县| 客服| 永仁县| 沛县| 德庆县| 华池县| 罗平县| 高尔夫| 英超| 青川县| 卢湾区| 新建县| 浙江省| 三明市| 永和县| 芜湖县| 巴彦县| 曲靖市| 盐山县| 宁德市| 休宁县| 虞城县| 济宁市|