面試某某公司bi崗位的時候,面試題中的一道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
13oppo
12vivo
18建表語句
-- ----------------------------
-- table structure for sale
-- ----------------------------
drop
table
ifexists
`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
1day))
as befor_date
from sale s left
join
(select id+
1as 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
andnotexists
(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
0end
)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面試題 求時間差之和 有重複不計
面試某某公司bi崗位的時候,面試題中的一道sqlskpwywg 題,咋看一下很簡單,寫的時候發現自己缺乏總結,沒有很快的寫出來。題目如下 求每個品牌的 天數 表sale為 營銷表,資料中存在日期重複的情況,例如id為1的end date為20180905,id為2的start date為201809...
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 ...