zoukankan      html  css  js  c++  java
  • 几道比较难的SQL题

    上条记录和下一条记录

    在展示博客文章时,在文章底部需要展示上一篇文章和下一篇文章,文章的排序当然是按照时间排序的。
    选定下一条时可以用limit 1来实现,选取上一条时可以倒序limit 1实现

    (SELECT * FROM article WHERE create_time<now_article_time ORDER BY create_time DESC LIMIT 1)
    UNION
    (SELECT * FROM article WHERE create_time>now_article_time ORDER BY create_time ASC LIMIT 1)
    

    显示行号

    Select a.*,(@rowNum:=@rowNum+1) as rowNo
    From a,(Select (@rowNum :=3) ) b
    

    通过变量rowNum来表示行号,在from子句中通过select语句给rowNum赋初值。这个过程涉及到SQL的执行顺序:即先执行from子句再执行select子句。

    这种写法效率比较高,使用复合SQL语句的方式实现效率比较低(行号通过select语句来实现)。

    MySQL打印学生成绩单

    学生成绩单有语文、数学、英语三门成绩,如下所示:
    语文 数学 英语
    1 2 3
    3 4 10
    10 2 8
    20 5 1
    7 4 8
    10 8 2
    10 7 2
    要求打印“rank(名次) sum(总分)”两列的成绩单(总分降序排列)。

    SELECT 1 + (SELECT COUNT(1)  FROM
                stu AS y WHERE
                y.chinese + y.math + y.english > x.chinese + x.math + x.english) AS rank,
        (x.chinese + x.math + x.english) AS sum_score
    FROM
        stu AS x ORDER BY sum_score DESC;
    

    这里用到了if函数,也可以通过SQL条件语句来实现:
    case 表达式 when 取值1 then 答案1 when 取值2 then 答案2 else 答案3 end
    这样写复杂度较高,下面这种方法比较简单。

    SELECT  rank, sum_score FROM
        (SELECT 
            IF(@last_sum = x.chinese + x.math + x.english, @rank, @rank:=@rank + 1) AS rank,
                (x.chinese + x.math + x.english) AS sum_score,
                (SELECT @last_sum:=x.chinese + x.math + x.english) AS yy
        FROM
            stu AS x, (SELECT @last_sum:=- 1, @rank:=0) AS nothing
        ORDER BY sum_score DESC) AS haha;
    

    这里用到的技巧如下:
    1、通过创建临时表、两重select来只选中某些列
    2、在where子句中执行变量的初始化
    3、在select子句中执行变量的更新
    4、通过定义变量last_sum来记录上一条记录 的信息
    5、通过比较上一条记录的总分跟当前记录的总分来决定是否让rank增加

    SQL中的case语句

    语法:

    case [input_expression]
    when when_expression then result_expression
    [...n]
    [else else_result_expression]
    end
    

    注:[]表示可选内容。
    1、demo1:case后带表达式

    select *,
           case sgroup
           when 1 then N'组1'
           when 2 then N'组2'
           when 3 then N'组3'
           else N'未知' end groupname
      from @stuinfo
    

    2、demo2:case后不带表达式

    select *,
           case
           when sgroup = 1 and gender = 'm' then N'第一组男生'
           when sgroup = 1 and gender = 'f' then N'第一组女生'
           when sgroup = 2 and gender = 'm' then N'第二组男生'
           when sgroup = 2 and gender = 'f' then N'第二组女生'
           when sgroup = 3 and gender = 'm' then N'第三组男生'
           when sgroup = 3 and gender = 'f' then N'第三组女生'
           else N'未知' end comment
      from @stuinfo
    

    3、demo3:在order by子句中使用case语句

    select * from @stuinfo
    order by
        case when @orderby = 1 then id end desc,
        case when @orderby = 2 then id end
    

    这里要用多个case,因为desc需要放在end 后面,否则会有语法错误。
    由此可以构造一道题:对一群学生成绩单进行排序,如果是男生按照数学成绩降序排列,如果是女生按照语文成绩降序排列,最终得到全体学生的成绩和名次。
    这个问题不使用case语句也能实现,但是使用case 语句更简洁、效率更高。

    一言以蔽之,case语句可以用在任何表达式中,有表达式的地方就可以有case语句。order by后面其实跟的也是表达式而不是列名。

    SQL语句实现数据库表的数据迁移

    国家标准分为强制性标准和推荐性标准,这两种标准的字段完全一致,当时建表时一时糊涂,分成了两个表。现在想合并force_standard、recommend_standard两张表为standard表,并加上字段is_force来表示该标准是否强制性标准。
    当然可以通过一段代码,for循环实现,但那样麻烦,用SQL只需要一句话。

    insert into standard(列名,列名,列名...is_force) 
    select 列名,列名,列名...,true from force_standard union
    select 列名,列名,列名...,false from recommend_standard
    
  • 相关阅读:
    时间格式
    分页1
    vs2010 VS2008 VS2005 快捷键大全
    css 常用标签
    JS Array数组操作
    CSS属性
    jquery 选择器大全
    @fontface
    以前写过的ajax基础案例(王欢huanhuan)
    Jquery操作下拉框(DropDownList)的取值赋值实现代码(王欢)
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/7188900.html
Copyright © 2011-2022 走看看