Mysql|数据分析搞懂这15道SQL题目笔试就稳了

这是最近数分面试小伙伴遇到的mysql面试题,在网上查了一下,没有完整答案,所以特意整理了一下,帮助正准备或已经在面试中的伙伴,每道题不止一种写法,不保证完全正确,供参考思路哈~ 欢迎留言交流,共同进步~

第一题:

现有以下三张表

CREATE TABLE `hospital` ( `HospitalId` varchar(36) NOT NULL,
 `HospitalName` varchar(100) DEFAULT NULL, 
`ProvinceName` varchar(45) DEFAULT NULL,
 `CityName` varchar(45) DEFAULT NULL, 
`Disabled` bit(1) NULL DEFAULT 0, 
PRIMARY KEY (`HospitalId`)
) COMMENT='医院表'
;
 
 CREATE TABLE `product` (
   `ProductId` varchar(36) NOT NULL,
   `ProductName` varchar(100) NULL,
   `Price` decimal(10, 2) NOT NULL COMMENT '单价',
   PRIMARY KEY (`ProductId`)
 ) COMMENT='产品表'
 ;
 
 CREATE TABLE `sales` (
   `SalesId` varchar(36) NOT NULL,
   `HospitalId` varchar(36) NOT NULL,
   `Period` date NOT NULL COMMENT '日期yyyy/mm/dd',
   `ProductId` varchar(36) NOT NULL,
   `SalesVolume` decimal(10, 2) NOT NULL COMMENT '销售数量',
   PRIMARY KEY (`SalesId`),
   CONSTRAINT `fk_hospitalid` FOREIGN KEY (`HospitalId`) REFERENCES `hospital` (`HospitalId`),
   CONSTRAINT `fk_productid` FOREIGN KEY (`ProductId`) REFERENCES `product` (`ProductId`)
 ) COMMENT='销量表'
 ;

写出SQL语句:查询产品名称=“A药品”,在北京医院2018~2019两年的销售“金额”,排除两年销售金额总和>1000000的医院,要求查询结果如下表。

思路:
1、首先将城市是北京,产品名称是A药品, 2018和2019年销售额之和大于 1000000 的医院id 和 医院名查询出来
2、考虑按月份显示销售额,这里为了代码简洁直接用了年份,通过 sum(if())算出各个医院的每年的销售额
3、最后将两个子查询 按照 医院id进行连接,得到符合条件的最终结果

答案:

SELECT * FROM
(SELECT
    hospitalid,hospitalname
FROM
    hospital WHERE cityname='北京' AND hospitalid IN (
    select hospitalid  from product LEFT JOIN sales ON product.productid = sales.productid
WHERE productname='a药品' AND YEAR(period) in (2018,2019)
GROUP BY hospitalid
HAVING SUM(price * salesvolume)  > 1000000
    )) as t1
INNER JOIN
(
SELECT hospitalid,
sum(if(YEAR(period) = '2018',price * SalesVolume ,0)) as '2018',
sum(if(YEAR(period) = '2019',price * SalesVolume ,0)) as '2019'
 FROM sales LEFT JOIN product on sales.ProductId = product.ProductId GROUP BY hospitalid) as t2
 
ON t1.hospitalid = t2.hospitalid

运行结果

第二题(与第一题同样的数据):

写出SQL语句,查询题1的销量表中2019年任意连续三个月销售额都>0的医院。
返回字段:HospitalId,SalesMonth(2019年销量>0的所有月份,逗号隔开)

思路:
1、写一个子查询,筛选出2019年,销售额>0的医院,窗口函数按医院id进行分组 按医院ID,日期排序,并建辅助列 row_num
2、通过第一个子查询得到的月份Period_month和辅助列row_num,做减法(目的是通过相等的差,判断是否连续)
3、对 两者之差 sig_num ,做个分组,count 大于等于3,即符合条件,最后用GROUP_CONCAT 将连续月份拼接起来

答案:

SELECT
    Hospitalid,
    count( sig_num ) AS count_sig_num,
    GROUP_CONCAT( Period_month ) 
FROM
    (
    SELECT
        Hospitalid,
        Period_month,
        row_num,
        CONVERT ( Period_month, signed ) - CONVERT ( row_num, signed ) AS sig_num 
    FROM
        (
        SELECT
            Hospitalid,
            MONTH ( Period ) Period_month,
            row_number() over ( PARTITION BY Hospitalid ORDER BY Hospitalid, Period ) row_num 
        FROM
            sales 
        WHERE
            YEAR ( Period ) = '2019' 
            AND salesvolume > 0 
        ) t1 
    ) t2 
GROUP BY
    Hospitalid,
    sig_num 
HAVING
    count_sig_num >= 3;
运行结果

第三题:

以下是微信聊天记录表

 CREATE TABLE `wechat` (
   `WechatId` varchar(36) NOT NULL,
   `WechatFriendId` varchar(36) NOT NULL COMMENT '每个ID表示一对好友',
   `ChatTime` datetime NOT NULL COMMENT '聊天时间',
   `IsSend` bit NOT NULL COMMENT '我方发送:1,用户回复:0',
   `Content` text NULL COMMENT '内容',
   PRIMARY KEY (`WechatId`),
 ) COMMENT='微信聊天';

写出SQL语句:按月统计2020年的微信回复率

发送次数 = 一组好友在一个自然天内的所有发送记录计为1次。

回复率计算公式 =(发送次数在两个自然天内被回复)/发送次数*100%

思路:
1、先统计 2020年每月的微信发送次数(注意每个日然人一日发送多次记为1次)
2、再统计 2020年每月的微信回复的次数(注意这里回复和发送的用户要对应,还有个重要条件48小时内回复)
3、算出 回复率 = 回复次数/发送次数

答案:

with send as(
SELECT  DATE_FORMAT(t1.ChatTime,'%Y-%m') cm,COUNT(1) send_cnt
FROM (
            select 
             ChatTime,
             count(distinct WechatFriendId) send_cnt
            from wechat
            where IsSend = 1 and year(ChatTime) = '2020'
            group by 1) t1
GROUP BY 1
 ),
 response as(
SELECT DATE_FORMAT(a.ChatTime,'%Y-%m') cm, 
     count(distinct a.WechatFriendId) resp_cnt
from
     (select WechatFriendId,ChatTime from wechat where year(ChatTime) = '2020' and IsSend=1) a
left join
     (select WechatFriendId,ChatTime from wechat where year(ChatTime) = '2020' and  IsSend=0) b
on
     a.WechatFriendId = b.WechatFriendId
where 
     datediff(b.ChatTime, a.ChatTime) <= 2 AND datediff(b.ChatTime, a.ChatTime) >= 0
 group by 1
 )
 select 
     cm, resp_cnt,send_cnt,concat(round(resp_cnt/send_cnt,4)*100,'%') as '回复率'
 from
     send join response using(cm)
运行结果

未完。。。 持续更新中。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容