SQL面試題:求時(shí)間差之和(有重復(fù)不計(jì))
面試某某公司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í)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL數(shù)據(jù)庫10秒內(nèi)插入百萬條數(shù)據(jù)的實(shí)現(xiàn)
假設(shè)現(xiàn)在我們要向mysql插入500萬條數(shù)據(jù),如何實(shí)現(xiàn)高效快速的插入進(jìn)去?本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-10-10MySQL中count()和count(1)有何區(qū)別以及哪個(gè)性能最好詳解
count是一個(gè)函數(shù),用來統(tǒng)計(jì)數(shù)據(jù),但是count函數(shù)傳入的參數(shù)有很多種,比如count(1)、count(*)、count(字段)等,下面這篇文章主要給大家介紹了關(guān)于MySQL中count()和count(1)有何區(qū)別以及哪個(gè)性能最好的相關(guān)資料,需要的朋友可以參考下2022-08-08mysql 5.7更改數(shù)據(jù)庫的數(shù)據(jù)存儲(chǔ)位置的解決方法
隨著MySQL數(shù)據(jù)庫存儲(chǔ)的數(shù)據(jù)逐漸變大,已經(jīng)將原來的存儲(chǔ)數(shù)據(jù)的空間占滿了,導(dǎo)致mysql已經(jīng)鏈接不上了。所以要給存放的數(shù)據(jù)換個(gè)地方,下面小編給大家分享mysql 5.7更改數(shù)據(jù)庫的數(shù)據(jù)存儲(chǔ)位置的解決方法,一起看看吧2017-04-04mysql 5.7.13 安裝配置方法圖文教程(linux)
這篇文章主要為大家詳細(xì)介紹了linux下mysql 5.7.13 安裝配置方法圖文教程,感興趣的小伙伴們可以參考一下2016-06-06mysql8.0.20配合binlog2sql的配置和簡單備份恢復(fù)的步驟詳解
這篇文章主要介紹了mysql8.0.20配合binlog2sql的配置和簡單備份恢復(fù)的步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Linux/UNIX和Window平臺(tái)上安裝Mysql
這篇文章主要為大家詳細(xì)介紹了Linux/UNIX和Window兩個(gè)系統(tǒng)上采用命令安裝Mysql的方法,感興趣的小伙伴們可以參考一下2016-05-05