CASE函数 sql server——分组查询(方法和思想) ref和out 一般处理程序结合反射技术统一执行客户端请求 遍历查询结果集,update数据 HBuilder设置APP状态栏

CASE函数

 

作用:

  1. 可以将查询结果集的某一列的字段值进行替换
  2. 它可以生成一个新列
  3. 相当于switch...case和 if..else

使用语法:

case 表达式/字段

when 值 then 自定义值

else

end as 别名

when 值 then:可以理解为当某个字段为某个值的时候,然后就返回自定义值将结果集的字段值进行替换

else:如果上面的when都不满足就执行else结果


常用用法一(case后面有字段或者表达式)

when关键字后面写固定值

case关键字后面如果有字段或者表达式,那么这种结构只能做等值判断,等值的意思是when关键字后面写了固定的值

示例图解:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

注意:该方式不能用于判断null

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏


常用方式二(case关键字后面没有字段或表达式)

when关键字后面写条件表达式

思考:

现在有个需求说,要求年龄字段这个人满足18岁或者年龄在某个范围,那么如果用上面说的等值判断,无法满足,因为字段要匹配的是一个范围

如果case关键字后面没有写字段或表达式,那么结构就相当于 if..elseif...else可以做范围判断,它可以使用null值判断

实例图解:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏


注意:

then 后面的值的类型 要与当前case范围内的保持一致

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

sql server——分组查询(方法和思想)

 

思想

先排序在汇总

sql server里分组查询通常用于配合聚合函数,达到分类汇总统计的信息。而其分类汇总的本质实际上就是先将信息排序,排序后相同类别的信息会聚在一起,然后通过需求进行统计计算。


使用GROUP BY进行分组查询

实例演示

--查询男女生的人数

在没有学习分组查询之前,我们可以安装常规的思路解决查询需求:

select count(*) from student where sex='男'

select count(*) from student where sex='女'

那么现在又要个需要时,查询每个班级的总人数

如果按照常规解决查询,那么我们应该思考的是:

1.每个班级,我们并不知道在表里有哪些班级,那么我们where 后的条件如何写?

2.如果该表里有1000个班级,那么我难道要写一千条where查询语句?

面对这样的问题 sql server为我们准备了Group by 关键字实现分组查询

在使用介绍Group by关键字之前,我们先来看看系统实现分组查询的原理和逻辑:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

映射成SQL语句:

select sex ,count(*)  as 人数  from student group by sex

这个简短的语句,经过上图的原理,应该要知道,第一步是先from查询表的所有信息,然后group by根据字段进行分组后在统计汇总

上面的案例是通过Count()函数进行统计,当然分组汇总还可以使用其他的聚合函数进行汇总。

使用GROUP BY 语句注意事项一:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

图中使用查询语句,包含一个字段和一个聚合函数为什么会报错呢?

原因,我们把两个字段分开来查询:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

总结:为了保证完整性,系统约定俗成,在使用了聚合函数的查询语句中,除了聚合函数,可以在查询列表上,要出现其他字段,那么该字段就必须为分组字段,而且该字段一定要跟随在GROUP BY关键字后面。

    与聚合函数一起出现在select后面进行查询的列,只有两种可能性:被聚合 、被分组


多列分组查询

--实例需求,查询每一个班级,男女生的人数

分析:显然需求是两组,每一个班需要划分组,男女也需要分组

实现图解:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

SQL语句:

select  GradeId,sex,COUNT(*)  from student group by GradeId,Sex order by GradeId

经验:搞清楚需要分几组,搞清楚分组的顺序,一轮一轮的分,系统是等分组之后才会进行汇总信息


使用HAVING子句

演示示例:--查询每一个班级男女生的人数,同时只需要显示人数数量超过3人的记录

分析:此查询显然是对上一个示例的多列分组进行筛选。

试在这学的知识范围内来解决此查询需求。。。。

一、那么就按照我们学的where来进行筛选

结果如图:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

这个错误告诉了我们:where里面不能出现聚合函数作为条件,失败!

二、既然不能使用聚合函数,那就给聚合函数取一个别名,让它当做一个列

结果如图:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

错误原因:原因是where是对源数据进行筛选的,也就是对from 后面的表进行筛选,既然是源数据,那么where去源数据表里找一个别名字段,怎么可能会有!所以才会报错

让我们来探讨一下,这里为什么不能使用where

1.需求是对分组之后的数据集进行筛选,where只针对数据表原始数据筛选

2.where关键字显然只能出现一次,而且根据查询的顺序,是先执行where条件筛选后得到的结果集,在进行的group by分组

解决办法,使用HAVING关键字:

HAVING核心:是对分组统计之后的结果集,进行数据的筛选

SQL语句:

select  GradeId,sex,COUNT(*)  as renshu from student  group by GradeId,Sex  having count(*)>=3 order by GradeId

where和having的不同:where是对原始数据进行筛选,having是对分组时候的数据进行筛选


查询语句的执行顺序

在这里引出查询机制里对查询语句里的关键字的执行顺序

查询关键字家族成员

select  top/distinct 字段列表 from 表列表 where 筛选条件 group by 分组字段列表 having  对分组之后得到的结果集筛选  order by 排序字段列表

执行顺序:

1.from

2.where

3.group by

4.having

5.根据select 关键之后的要显示的字段,进行结果集显示

6.order by 对最终结果集进行排序

7.top/dictinct

ref和out

 

Ref 把值传递变成引用传递

当调用一个方法时,传入的参数是一个值类型,那么需要方法将这个传入的值类型的变量值改变受到影响,我们可以使用ref 关键字进行处理实现。

观察一:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

结论:

根据值类型和引用类型的特点,值类型是赋值,是复制传递的是栈上存储的具体值信息,如图实参变量"a"将100赋值给方法形参"num"变量。那么值类型的改变只会影响值的本身,形参的改变没有形象到变量"a"。

加上ref修饰形参:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

结论:

通过ref关键字,此时传递变量a的时候,实参把引用传给了形参,那么说明了这两个变量将指向同一个引用地址,变量num在方法中的改变会影响到变量a

输出结果:101

使用ref关键字的时候需要注意:

1.用了ref关键的方法,必须在参数列表上加上ref关键字,在调用该方法的时候也要加上ref关键字。

2.作为传入修饰了ref的方法的实参变量,必须赋初始值

作用总结:如果想使一个值类型的变量,通过传入一个方法进行改变,可以使用ref


OUT 让方法返回多个值

从语法规则上来讲,一个方法只能有一个返回值,如果return多个值简直是天方夜谭,如图:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

通过out的方式实现:

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏
  static void Main(string[] args)
        {

            int a ;
            changeNum(out a);
            Console.WriteLine(a); //结果为101
        }

        static stringchangeNum(out int num)
        {
            num = 100;
            num++;
             return "ok";
        }
CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

使用out关键字需要注意:

1.在方法定义和方法调用时,都要加上out关键字

2.方法参数列表上修饰了out关键字的变量,必须在方法体赋初始值,对于方法调用提供的实参变量可以不需要赋值。


面试题

ref与out的区别是什么?

使用ref的时候要传入相应方法的实参变量,必须赋值。而out在调用的时候只用声明,但是在方法内部,修饰了out形参必须赋值。

ref和out有着异曲同工之妙,都可以实现相同的功能,ref侧重于将值类型的值传递改变为引用传递,out侧重于对于一个方法返回多个值

一般处理程序结合反射技术统一执行客户端请求

 

思考:

在开发中,如果使用了模板技术+一般处理程序开发,应用中用户的请求可能在程序中都存在一个共性的操作。

例如,每当执行请求时要检查用户是否是登陆,请求时检查用户是否具有相应权限等等的共性的操作,我们不可能每个页面都写上对于操作,那样显然不符合面向对象的思想,存在大量冗余。

如何去解决呢?

解决思路:

  • 创建一个父类实现IHttpHandler接口,让处理请求的一般处理程序实现这个接口,当一般处理程序接收到请求时,去统一执行父类里的ProcessRequest()方法。
  • 客户端发出的请求,要约定俗成的带上一个action的参数,参数的值就是一般处理程序里要执行的方法。
  • 当执行父类的ProcessRequest()方法时,利用反射获取当前一般处理程序的Type,前面说了action的值代表了当前请求执行的操作是什么,那么利用反射找到指定的方法然后执行它。

这样而来,可以让共性的操作在父类里完成,而具体的方法实现在子类里完成


范例代码:

子类

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using Blog.Common;
 6 namespace Blog.UI.Article_category
 7 {
 8     /// <summary>
 9     /// Handler1 的摘要说明
10     /// </summary>
11     public class Article_category_Controller : BaseHandler
12     {
13
14         //方法名都要约定:每个请求名都为action,action的值,都是一般处理程序的方法
15         public void list(HttpContext context)
16         {
17          string output=   RazorHelper.RazorParsre("/Article_category/template/Blog_Category.cshtml");
18          context.Response.Write(output);
19         }
20
21
22
23     }
24 }
CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

父类

CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Reflection;
 5 using System.Web;
 6 using System.Web.SessionState;
 7 namespace Blog.UI
 8 {
 9
10
11     public class BaseHandler:IHttpHandler,IRequiresSessionState
12     {
13
14         //一般处理程序会第一个执行    ProcessRequest()方法,它自己没有,会找父类要,让父类统一来执行请求
15         public void ProcessRequest(HttpContext context)
16         {
17
18             /*
19              在处理请求操作之前,这里可以处理应用程序要遵循的共性操作
20
21              */
22
23
24
25
26             //客户端每个请求约定俗成url带上一个参数叫action,action代表该请求执行什么操作
27             if (string.IsNullOrEmpty(context.Request["action"]))
28             {
29                 return;
30             }
31             string action = context.Request["action"];
32
33             //调用父类的方法,会是子类handler,利用反射获得类型
34             Type ty = this.GetType();
35             //根据这个类型,找到和action同名对应的方法,也就是说用action找到当前请求要执行的方法
36             MethodInfo method = ty.GetMethod(action);
37             if (method!=null)
38             {
39                 method.Invoke(this, new object[] { context });  //context是参数
40                 return;
41             }
42
43
44         }
45
46
47
48
49         public bool IsReusable
50         {
51             get
52             {
53                 return false;
54             }
55         }
56
57
58
59     }
60
61
62
63
64 }
CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

遍历查询结果集,update数据

 
CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏
 1 set rowcount 0
 2 select NULL mykey, * into #mytemp from  dbo.DIM_DISTRIBUTOR
 3
 4 set rowcount 1
 5 update #mytemp set mykey = 1
 6
 7 declare @i int
 8 set @i=1
 9 while @@rowcount > 0
10 begin
11     set rowcount 0
12     select * from #mytemp where mykey = 1
13
14     declare @zj varchar(222)
15         select @zj=DISTRIBUTORID from #mytemp where mykey = 1
16          print @i
17
18      update DIM_DISTRIBUTOR set NAME='用户测试数据'+CAST(@i as varchar(222))    where DISTRIBUTORID=@zj
19
20     set @i=@i+1
21     delete #mytemp where mykey = 1
22     set rowcount 1
23     update #mytemp set mykey = 1
24 end
25 set rowcount 0
CASE函数  sql server——分组查询(方法和思想)  ref和out  一般处理程序结合反射技术统一执行客户端请求  遍历查询结果集,update数据   HBuilder设置APP状态栏

HBuilder设置APP状态栏

 

一、 前言

  状态栏就是手机屏幕最顶部的区域,包括了:信号、运营商、电量等信息。通常APP都有属于自己的色调风格,为了达到整体视觉美观,通常会设置状态栏和标题栏的色调设置成一致。

  图例:

  


二、状态栏状态类型

  1. 默认
  2. 变色(设置颜色)
  3. 透明(沉浸式)
  4. 消失(全屏)

三、状态栏变色

  1.效果如图:

  2.根据色调设置状态栏文字颜色,文字颜色只提供两种值:light(白色)、dark(黑色)

  3.设置标题栏背景颜色

  4.设置状态栏背景颜色,颜色值为16进制

  示例代码:

 
1 <link href="css/mui.min.css" rel="stylesheet"/>
2 .mui-bar{ background-color: red;}
3 </link>
4 <script>
5 mui.plusReady(function(){
6 plus.navigator.setStatusBarStyle('light');
7 plus.navigator.setStatusBarBackground('#FF0000');
8 });
9 </script>    
 

  注意事项:

  背景色终端支持仅:Android5及以上系统支持;iOS7.0及以上系统支持。

  文字色终端支持仅:Android5只有小米和魅族支持,Android6及以上所有安卓支持;iOS7及以上支持。


  

四、状态栏透明(沉浸式)

  1.效果如图:

  

          (将背景图片和状态栏、标题栏贯通了)

  

  2.运用实战(登录界面)

  需求描述:将背景设置成图片,图片可以适应不同设备的分配率(响应式),将状态栏的背景设置成透明,背景图片覆盖状态栏至屏幕顶部。  

 
 <style>
    html,body{height: 100%;width: 100%;}
    body{
      background:url(image/background.png)no-repeat;
      background-size:100% 100%;
        filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image/background.png',sizingMethod='scale');
    }
    </style>
 
mui.plusReady(function(){
    plus.navigator.setStatusBarStyle('light');
});
"plus": {
    "statusbar": {
        "immersed": true
    }
}

  3.沉浸式延伸的问题

   由于沉浸式模式是在manifest.json文件配置,作为了一个固定全局的设置,沉浸式的设置可能只是针对部分页面,那么对其他的页面都牵连了。

   导致的效果如图:

  

              (状态栏的高度被忽略)

  解决代码:

  mui.plusReady(function(){
    plus.webview.currentWebview().setStyle({
        statusbar:{background:'#ff0000'},top:0,bottom: 0
  });
 });

  background属性,设置状态栏的背景色。


五、 全屏显示(没有状态栏)

在应用中可调用5+ API动态改变应用是否全屏显示的状态:

 
function fullscreen(){
        // 设置应用全屏显示!
        plus.navigator.setFullscreen(true);
}
function unfullscreen(){
        // 设置应用非全屏显示!
        plus.navigator.setFullscreen(false);
}
function isfullscreen(){
        // 查询应用当前是否全屏显示!
        console.log( "是否全屏:"+(plus.navigator.isFullscreen()?"是":"否") );
}
 

知识改变命运
上一篇:PHP取整函数之ceil,floor,round,intval的区别


下一篇:JavaScript中的Math.ceil()、Math.round()、Math.floor()