面試某某公司bi崗位的時候,面試題中的一道sqlskpwywg**題,咋看一下很簡單,寫的時候發現自己缺乏總結,沒有很快的寫出來。
題目如下:
求每個品牌的**天數
表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
13oppo
12vivo
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-0程式設計客棧8-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 betwee 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 |
+-------+----------+
|www.cppcns.com 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面試題:求時間差之和(有重複不計)
本文位址:
SQL面試題 求時間差之和(有重複不計算)
面試某某公司bi崗位的時候,面試題中的一道sql題,咋看一下很簡單,寫的時候發現自己缺乏總結,沒有很快的寫出來。題目如下 求每個品牌的 天數 表sale為 營銷表,資料中存在日期重複的情況,例如id為1的end date為20180905,id為2的start date為20180903,即id為1...
SQL 求時間差
前兩天在寫程式的時候,為了計算兩個日期相差的天數,真是大費周折啊,我才開始 的時候想的是把 時間格式轉換為 long 型,後來一想,不對進製不同啊,後來我想到了資料庫,用 sql2005 中的datediff 函式,問題是解決了,可是每次都得和資料庫互動啊!終於同事的乙個大哥交 了乙個方法,這個方法...
一道與時間差有關的SQL面試題
題目 一組聯絡歷史 總共500萬條 id 主叫號碼 被叫號碼 通話起始時間 通話結束時間 通話時長 1 98290000 0215466546656 2007 02 01 09 49 53.000 2007 02 01 09 50 16.000 23 2 98290000 021546654666 ...