• SQL练习题(4),持续更新中


    声明:所有题目均是百度搜索,再由自己整理出来的,并非自己出的题。

    1. 用一条SQL 语句 查询出每门课都大于80 分的学生姓名

    name course score
    张三 语文 81
    张三 数学 75
    李四 语文 76
    李四 数学 90
    王五 语文 81
    王五 数学 100
    王五 英语 90

    解法一:

    每门课都大于80分,也就是说学生的所有课的最小分数大于80分MIN(score)>80再根据名称进行排序,HAVING在分组的后的结果种进行筛选

    SELECT NAME FROM `testscore` GROUP BY NAME HAVING MIN(score)>80;

    解法二:

    先查出每个学生的姓名和每门课程的最小分的结果集

    再在查出的结果集的基础上查询姓名,并使用大于80分的条件进行筛选

    SELECT NAME FROM (
    SELECT NAME, MIN(score) AS msc FROM `testscore` GROUP BY NAME) AS t1 
    WHERE t1.msc>80;

    解法三:

    先查出有任一门课程分数小于80分的学生姓名的结果集

    再排除掉上述结果集里的姓名,便查出大于80分的学生姓名,需用DISTINCT去重

    SELECT DISTINCT NAME FROM testscore WHERE NAME NOT IN (
    SELECT NAME FROM `testscore` WHERE score<80);

    解法四:

    使用NOT EXISTS特性,不关心子查询中的结果,

    如果子查询有返回记录,那么就排除当前记录,

    如果子查询没有返回记录,那么就输出当前记录。

    SELECT DISTINCT NAME FROM testscore t1 WHERE NOT EXISTS (
    SELECT * FROM testscore t2 WHERE t1.name=t2.name AND t2.score<80);

    解法五:

    将score<80作为单独的一列,满足条件为1,不满足为0

    再通过相加可以得到和,满足条件和=0也就是每一门分数都大于80才会得0.

    SELECT NAME FROM `testscore` GROUP BY NAME HAVING SUM(score<80)=0;

    解法六:

    查出所有记录条数

    查出大于80分的记录条数

    再使用两个记录条数比对,查两个的并集

    SELECT * FROM
    (SELECT NAME,COUNT(1) AS c1 FROM `testscore` GROUP BY NAME) t1,
    (SELECT NAME,COUNT(1) AS c2 FROM `testscore` WHERE score>80 GROUP BY NAME) t2
    WHERE t1.name=t2.name AND t1.c1=t2.c2;

    解法七:

    1.与解法六思路类似,在分组的结果上使用每个学生的分数记录条数和大于80分的记录条数进行比较,相等则说明都每门课程大于80分。

    SELECT NAME FROM `testscore` GROUP BY NAME HAVING COUNT(1)=SUM(IF (score>80,1,0));

    解法八:

    左连接查询,通过连接表查询出t2表中王五的数据为null

    再根据条件筛选出t2表中名字为null的

    SELECT DISTINCT t1.`name` FROM `testscore` AS t1
    
    LEFT JOIN (SELECT * FROM `testscore` WHERE score<=80) AS t2
    
    ON t1.name=t2.name
    
    WHERE t2.name IS NULL;

    (求最高分成绩的学生信息)思路

    -- 先找出最高分,查出来的结MAX(score)=100

    SELECT MAX(score) FROM `testscore`

    -- 再找出所有分数等于最高分的成绩

    SELECT * FROM `testscore` WHERE score=100

    -- 然后两条语句结合 (不相关子查询)

    SELECT * FROM `testscore` WHERE score=(SELECT MAX(score) FROM `testscore`);

    (求 每个同学最高分的成绩)

    解法一:

    SELECT NAME,MAX(score) FROM `testscore` GROUP BY NAME;

    解法二:

    相关子查询:依赖外部查询的数据,外部查询每执行一次,子查询就执行一次

    SELECT * FROM `testscore` t1 WHERE t1.`score`=(
    SELECT MAX(score) FROM `testscore` t2 WHERE t2.`name`=t1.`name`);

    -- (求大于平均分的成绩信息)

    SELECT * FROM `testscore` WHERE score > (SELECT AVG(score) FROM `testscore`);

    2. 现有学生表如下:

    自动编号 学号 姓名 课程编号 课程名称 分数

    1 2005001 张三 0001 数学 69

    2 2005002 李四 0001 数学 89

    3 2005001 张三 0001 数学 69

    删除除了自动编号不同, 其他都相同的学生冗余信息

    delete tablename where 自动编号 not in (
    
        select min( 自动编号)
        from tablename
        group by 学号, 姓名, 课程编号, 课程名称, 分数
    
    )

     

    3. 一个叫 team 的表,里面只有一个字段name, 一共有4 条纪录,分别是a,b,c,d, 对应四个球对,现在四个球对进行比赛,用一条sql 语句显示所有可能的比赛组合

    表自连结先求出多种比赛组合的笛卡尔积,

    再用小于排除重复的项

    select a.name, b.name
    
    from team a, team b
    
    where a.name < b.name

     

    4. 请用SQL 语句实现:从TestDB 数据表中查询出所有月份的发生额都比101 科目相应月份的发生额高的科目。

    请注意:TestDB 中有很多科目,都有1~12月份的发生额。

    AccID :科目代码,Occmonth :发生额月份,DebitOccur :发生额。

    数据库名:JcyAudit ,数据集:Select * from TestDB

    select a.*
    
    from TestDB a,
    
        (select Occmonth, max(DebitOccur) as Debit101ccur
    
        from TestDB
    
        where AccID='101'
    
        group by Occmonth) b
    
    where a.Occmonth = b.Occmonth and a.DebitOccur > b.Debit101ccur

     

    5. 把 a表 的数据查询出 b表的结果 (行转列)

    a表

    year

    month

    amount

    1991

    1

    1.1

    1991

    2

    1.2

    1991

    3

    1.3

    1991

    4

    1.4

    1992

    1

    2.1

    1992

    2

    2.2

    1992

    3

    2.3

    1992

    4

    2.4

    b表

    year

    m1

    m2

    m3

    m4

    1991

    1.1

    1.2

    1.3

    1.4

    1992

    2.1

    2.2

    2.3

    2.4

    解法一:子查询

    SELECT `year`, 
        (SELECT amount FROM amount m WHERE MONTH=1 AND m.year=amount.year) AS m1,
        (SELECT amount FROM amount m WHERE MONTH=2 AND m.year=amount.year) AS m2,
        (SELECT amount FROM amount m WHERE MONTH=3 AND m.year=amount.year) AS m3,
        (SELECT amount FROM amount m WHERE MONTH=4 AND m.year=amount.year) AS m4
    FROM amount GROUP BY YEAR

    解法二:CASE语句

    SELECT `year`,
    SUM(CASE WHEN `month`='1' THEN amount ELSE 0 END) m1,
    SUM(CASE WHEN `month`='2' THEN amount ELSE 0 END) m2,
    SUM(CASE WHEN `month`='3' THEN amount ELSE 0 END) m3,
    SUM(CASE WHEN `month`='4' THEN amount ELSE 0 END) m4
    FROM amount  GROUP BY `year` 

    解法三:IF语句

    SELECT `year`, 
    SUM(IF(`month`='1',amount,0)) AS m1,
    SUM(IF(`month`='2',amount,0)) AS m2,
    SUM(IF(`month`='3',amount,0)) AS m3,
    SUM(IF(`month`='4',amount,0)) AS m4
    FROM amount GROUP BY `year`

    6. 有表A,结构如下:

    p_ID p_Num s_id

    1 10 01

    1 12 02

    2 8 01

    3 11 01

    3 8 03

    其中:p_ID为产品ID,p_Num为产品库存量,s_id为仓库ID。

    请用SQL语句实现将上表中的数据合并,合并后的数据为:

    p_ID s1_id s2_id s3_id

    1 10 12 0

    2 8 0 0

    3 11 0 8

    其中:s1_id为仓库1的库存量,s2_id为仓库2的库存量,s3_id为仓库3的库存量。如果该产品在某仓库中无库存量,那么就是0代替。

    select p_id,
    
        sum(case when s_id=1 then p_num else 0 end) as s1_id,
    
        sum(case when s_id=2 then p_num else 0 end) as s2_id,
    
        sum(case when s_id=3 then p_num else 0 end) as s3_id
    
    from myPro group by p_id

    7.问题:请用一条SQL语句查询出每个科目平均分最高的班级名称

    class表

    classID className
    1 一班
    2 二班
    3 三班
    4 四班

    score表

    studentID name classID subject grade
    STD001 张三 1 数学 85
    STD002 李四 2 语文 90
    STD003 小红 1 数学 80
    STD004 小明 3 语文 88
    STD005 小花 3 语文 100
    STD006 大黄 2 数学 90
    STD007 大哥 2 数学 84
     SELECT  className,`subject`,MAX(average)
    
     FROM (
    
     SELECT `subject`, className, AVG(grade) AS average
    
     FROM score a, class b
    
     WHERE a.`classID`=b.`classID`
    
     GROUP BY a.classID,`subject`
    
    ) t1
    
    GROUP BY `subject`
    
    HAVING MAX(average);

     

    8.请将下表图1数据查询到图2的结果 (列转行)

    a表

    Name

    Chinese

    Math

    English

    张三

    85

    92

    87

    李四

    96

    89

    100

    王五

    91

    83

    98

      b表

    name

    course

    score

    张三

    语文

    85

    张三

    英语

    87

    张三

    数学

    92

    李四

    数学

    89

    李四

    语文

    96

    李四

    英语

    100

    王五

    数学

    83

    王五

    语文

    91

    王五

    英语

    98

    SELECT * FROM (
    
    SELECT NAME, '语文' AS course, Chinese AS score FROM asaa
    
    UNION
    
    SELECT NAME, '数学' AS course, math AS score FROM asaa
    
    UNION
    
    SELECT NAME, '英语' AS course, english AS score FROM asaa
    
    ) n
    
    ORDER BY n.name,n.score

    9.请将 a 表数据查询到 b 表的结果 (行转列)

    a表

    name

    course

    score

    张三

    语文

    85

    张三

    英语

    87

    张三

    数学

    92

    李四

    数学

    89

    李四

    语文

    96

    李四

    英语

    100

    王五

    数学

    83

    王五

    语文

    91

    王五

    英语

    98

    b表

    Name

    Chinese

    Math

    English

    张三

    85

    92

    87

    李四

    96

    89

    100

    王五

    91

    83

    98

    -- 解法一:CASE语句
    SELECT NAME,
    
    SUM(CASE course WHEN '语文' THEN score ELSE 0 END) AS Chinese,
    
    SUM(CASE course WHEN '数学' THEN score ELSE 0 END) AS Math,
    
    SUM(CASE course WHEN '英语' THEN score ELSE 0 END) AS English
    
    FROM score GROUP BY NAME;
    -- 解法二:IF语句
    
    SELECT NAME,
    
    SUM(IF(course='语文',score,0)) AS Chinese,
    
    SUM(IF(course='数学',score,0)) AS Math,
    
    SUM(IF(course='英语',score,0)) AS English
    
    FROM score GROUP BY NAME;

     

     

  • 相关阅读:
    学习笔记|数组的扩展
    javascript日期 时间处理类库
    v-if v-for同时使用 解决eslint报错问题
    跳出foreach循环
    live-player live-pusher惨案
    TypeError: Object(…) is not a function
    实现垂直水平居中的方法
    面试时候遇到的笔试题
    ajax跨域
    Bootstrap响应式相关
  • 原文地址:https://www.cnblogs.com/xianyulouie/p/11041769.html
Copyright © 2020-2023  润新知