面试遇到的SQL语句编写问题,求解答

白菜1031
  • 5.4k

题目描述

面试遇到这样一个问题:
有一个用户下载文件的表 'file_download',如下:

id uid fid status
1 1 1 0
2 1 1 1
3 2 1 1
4 2 2 0
5 2 2 1
6 1 3 1
7 3 3 0

...

uid 代表用户ID,fid 代表文件ID,`status代表文件下载状态,0是失败,1是成功。
用户若下载文件失败,可以继续下载,一旦下载成功,就不会再下载该文件。

让查出用户第一次下载文件就成功的记录。

自己的思路

我给的答案是这样的:

SELECT * FROM file_download GROUP BY uid,fid HAVING `status`=1;

但是面试官似乎不太满意,问我是否还有其他的方法?

回复
阅读 1.8k
4 个回答
_TNT_
  • 6.7k
✓ 已被采纳

随便写的…应该不是最优解,但是结果应该是对的

select sum(id) id, uid, fid, count(*) c, sum(status) s
from file_download
group by uid, fid
having c = 1
   and s = 1;

解释一下,因为要查 第一次下载文件就成功的记录,所以

  1. 下载要成功,需要有 status = 1 的记录
  2. 下载成功之后就不会再下载,所以sum(status) group by uid, fid 得到的结果只有 0 或者 11 表示成功
  3. 第一次就下载成功表示只下载了一次,所以需要 count(*) group by uid, fid1
  4. 不知道是否需要id,因为聚合了所以不能直接拿id,但是因为对应的数据只有一条,所以随便放一个sum(id)或者min(id)之类的都可以取到id
Lin阿某
  • 1
新手上路,请多包涵

SELECT count(*) c,id,uid,fid,status FROM file_download GROUP BY uid,fid having c = 1

Tuesday
  • 138

楼上们的回答应该还要加个where 判断一下status=1 防止第一次失败后, 它就没下载了.

但我有新的想法. 必须加上排序.

SELECT id,uid,fid,status FROM file_download GROUP BY uid,fid ORDER BY id ASC having status = 1

SELECT
COUNT(*) c,
id,
    uid,
    fid,
STATUS 
FROM
    file_downloads GROUP BY uid,fid
    HAVING c =1 AND STATUS = 1;
宣传栏