欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

sql大全_长期更新

程序员文章站 2022-05-07 15:01:50
...

1、Mybatis和Hibernate

1.1、获取结果为list<map<String,Object>>

1.1.1、mybatis

解释

1、返回类型必须是java.util.HashMap

2、map中的value 必须是Objecrt


1.1.1.1、mapper接口**

public interface HealerJeanMapper {
     List<Map<String,Object>> sqlMap();
}
1.1.1.2、mapper.xml
<select id="sqlMap" resultType="java.util.HashMap">
  SELECT h.id as id ,h.subject as subject FROM  healerjean  h;
</select>
1.1.1.3、controller测试

@RequestMapping("sqlMap")
@ResponseBody
public List<Map<String,Object>> sqlMap(){
    return healerJeanMapper.sqlMap();
}

sql大全_长期更新

1.1.2、Jpa分组制作

  • 1、mapper.xml
@Query(value = "select new map(g.department as department,count(*) as count) from GraduateDestination g  group by g.department")
 List<Map<String,Object>> getAcademyEmplo(String graduateDate);

  • 2、使用
 Map<String ,Integer> academyEmploMap=new HashMap<>();
 List<Map<String,Object>> list = destinationRepostiory.getAcademyEmplo(graduateDate);
 for(Map<String,Object> map:list){
	String key =  map.get("department").toString() ;
    String value = Integer.parseInt(map.get("count").toString()) ;
    emploMap.put(key,value);
 }

1.2、resultMap作为Mybatis返回类型

解释

1、property 实体类中的属性名

2、column默认是数据表的列名,或者比如

1.2.1、mapper.xml

<select id="select" parameterType="Query" resultMap="BaseResultMap">
    select *   from scf_contract
</select>

<select id="select" parameterType="Query" resultMap="BaseResultMap">
    select c.id as user_id   from scf_contract c
</select>

1.2.2、resultMap


  <resultMap id="BaseResultMap" type="com.taotao.pojo.TbUser" >
    <id column="user_id" property="id" jdbcType="BIGINT" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="phone" property="phone" jdbcType="VARCHAR" />
    <result column="email" property="email" jdbcType="VARCHAR" />
    <result column="created" property="created" jdbcType="TIMESTAMP" />
    <result column="updated" property="updated" jdbcType="TIMESTAMP" />
  </resultMap>

1.3、If标签的使用


<select id="findCustomerList" resultType="com.entity.db.customer.Customer">
    SELECT t.* from crm_customer t
    WHERE t.isVisiblisVisiblee = 1
    <if test="name != null and name != ''">
        and t.name like CONCAT('%','${name}','%' )
    </if>
    <if test="status != null">
        and t.status = #{status}
    </if>
</select>

1.4、where标签和trim的使用

解释

1、where标签会使sql语句自动加上where

2、 trim标签内sql语句 ,去除 ”前“,”后“ 内容、加前后缀

  • suffixOverrides= “,” 去除多余的后缀 ','
  • prefixOverrides=“and” 去除多余的前缀 'and '
  • **prefix="(" 加前缀 **
  • **suffix=")" 加后缀 **
<select id="selectByExample" parameterType="ScfContractQuery" resultMap="BaseResultMap">
    select
    <trim suffixOverrides=",">
        <include refid="Base_Column_List" />
    </trim>
    from scf_contract
    <include refid="Example_Where_Clause" />
</select>



<sql id="Example_Where_Clause">
    <where>
        <trim prefix="(" prefixOverrides="and" suffix=")">
            <if test="refSysFileId != null and refSysFileId != ''">
                and ref_sys_file_id = #{refSysFileId,jdbcType=VARCHAR}
            </if>
        </trim>
    </where>
</sql>

1.5、foreach标签 的使用

<if test="statusList != null and statusList.size() > 0">
    and status in
    <foreach collection="list" index="index" item="item" 
             open="(" separator="," close=")">
        #{item}
    </foreach>
</if>

1.6、choose when 标签 (相当于if else)的使用

<choose>
    <when test="flag == 1">
        and t.status = 0
    </when>
    <when test="flag == 2">
        and t.status = 1
    </when>
    <when test="flag == 3">
        and t.expressStatus = 1
    </when>
    <when test="flag == 4">
        and t.status = -2
    </when>
    <otherwise>
    </otherwise>
</choose>

1.7、制作参数map值在mybatis的mapper.xml使用

1.7.1、controller接收参数

@RequestMapping("data")
@ResponseBody
public ResponseBean data(String name,
					  Integer type,
					  Integer status,
                      @RequestParam(value = "page",defaultValue = "0") Integer page){
  
        int pageSize = 15;
        Pageable pageable = new PageRequest(page,pageSize);
        Page<AppInfoData> dataPage = skinsService.findList(pageable,
                                                           "name",name,
                                                           "type",type,
                                                           "status",status);
        return ResponseBean.buildSuccess(dataPage);
}

1.7.2、service 制作map参数

pageable 主要是利用里面的参数制作limit参数的

@Override
public Page<AppInfoData> findList(Pageable pageable, Object... param)  {

    Map data = MyBatisHelper.mergeParameterMap(pageable,param);
    if(data.get("startDate") != null){
        Date startDate = (Date) data.get("startDate");
        data.put("startDate", .DateHelper.getDateFirstTime(startDate));
    }
    if(data.get("endDate") != null){
        Date endDate = (Date) data.get("endDate");
        data.put("endDate",DateHelper.getDateLastTime(endDate));
    }

    List<SkinAppInfoData> dataList = skinsMapper.findSkinList(data);
    Long count = skinsMapper.countSkinList(data);
    return new PageImpl<SkinAppInfoData>(dataList,pageable,count);
}

1.7.3、MyBatisHelper工具类

public class MyBatisHelper {
    public static final String PARAM_OFFSET = "offset";
    public static final String PARAM_LIMIT = "limit";

    public MyBatisHelper() {
    }

    public static Map<String, Object> mergeParameterMap(Object... parameter) {
        if (parameter.length % 2 != 0) {
            throw new IllegalArgumentException("parameter须为key-value对应参数");
        } else {
            Map<String, Object> map = new HashMap();

            for(int i = 0; i < parameter.length; i += 2) {
                map.put(parameter[i].toString(), parameter[i + 1]);
            }

            return map;
        }
    }

    public static Map<String, Object> mergeParameterMap(Pageable pageable, Object... parameter) {
        if (parameter.length % 2 != 0) {
            throw new IllegalArgumentException("parameter须为key-value对应参数");
        } else {
            Map<String, Object> map = new HashMap();
            map.put("offset", pageable.getOffset());
            map.put("limit", pageable.getPageSize());

            for(int i = 0; i < parameter.length; i += 2) {
                map.put(parameter[i].toString(), parameter[i + 1]);
            }

            return map;
        }
    }
}

1.7.4、mapper接口

public interface SkinsMapper {

    public List<SkinAppInfoData> findSkinList(Map param);

}

1.7.5、mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.duodian.admore.dao.db.skins.SkinsMapper">

    <select id="findSkinList" resultType="com.duodian.admore.data.skins.SkinAppInfoData">
        SELECT
            A1.`appid`,
            A1.`appSecret`,
            A1.`icon`,
            A1.`makerMemo`,
            A1.`haveBackstage`,
            A1.`channelJson`,
            A1.`filePath`
        FROM  `skin_app_info_check`  a1
        where A1.status not in (9)
        <if test="name != null and name != ''">
            AND (A1.trackId = #{name}
            OR A1.name LIKE CONCAT('%',#{name},'%' )
            OR A1.appid LIKE CONCAT('%',#{name},'%' )
            OR A1.appSecret LIKE CONCAT('%',#{name},'%' )
            )
        </if>
        <if test="type != null and type != '' ">
            and A1.type = #{type}
        </if>
        <if test="status != null and status != '' ">
            and  A1.status = #{status}
        </if>
        order by A1.cdate desc
        <if test="offset != null and limit != null">
            limit #{offset}, #{limit}
        </if>
    </select>

</mapper>

1.8、query对象作为参数传入

1.8.1、query对象

public class SysUserQuery implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private Integer offset;
    private Integer limit;
    private Date startDate;
    private Date endDate ;
    private String userid;
    private String userParam;
    private Integer status;

}


1.8.2、controller层

@RequestMapping("data")
@ResponseBody
public ResponseBean data(@RequestParam(defaultValue = "0")Integer page, 
                         @RequestParam(defaultValue = "15")Integer pageSize, 
                         SysUserQuery query){

        Pageable pageable = new PageRequest(page,pageSize);
        return ResponseBean.buildSuccess(sysDingUserService.getData(pageable,query));
}

1.8.3、service层,将pageable分页对象放入

 @Override
    public Page<SysDingUser> getDingUserData(Pageable pageable, SysUserQuery query) {

        query.setOffset(pageable.getOffset());
        query.setLimit(pageable.getPageSize());

        List<SysDingUser> list = sysMapper.findSysDingUserList(query);
        Long count = sysMapper.countSysDingUser(query);
        return new PageImpl<>(list, pageable, count);
    }
}

1.9、resultType 返回对象

解释

1、对于数据库字段匹配的,可以直接选择

2、对于不匹配的使用 as 转化

<select id="findRedStartSpread" 
        parameterType="com.duodian.RedStartSpreadQuery" 
        resultType="com.duodian.RedStartHistoryBean">
    select
    k.trackId,
    e.smallIcon,
    e.formattedPrice,
    e.price,
    e.fileSizeBytes,
    e.trackName,
    f.name admName,
    a.nickName userName,

    DATE_FORMAT(k.spreadDateStart, '%Y-%m-%d') AS ymd,
    k.userId
    FROM
    redstart_spread k

1.10、不使用注解@Param 只有一个参数传入

解释

使用了@Param正常情况下,直接写参数名字,也可以直接传入数据,但是只有一个参数传入的时候,,不能直接写参数名字了 而是使用下面的_parameter

1.10.1、mapepr接口
List<CustomerChance> getCustomerList(Long adminId);

1.10.2、mapper.xml
<select id="getCustomerList" resultType="com.duodian.db.CustomerChance">
    select *
    from `crm_customer_chance`  c
    where c.isVisible = 1
    <if test="_parameter != null">
        and c.adminId = #{_parameter}
    </if>
</select>

1.11、原生符号

解释

被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”。

此标记用于xml文档中,我们先来看看使用转义符的情况。我们知道,在xml中,”<”、”>”、”&”等字符是不能直接存入的,否则xml语法检查时会报错,如果想在xml中使用这些符号,必须将其转义为实体,如”<”、”>”、”&”,这样才能保存进xml文档。

1.11.1  举例说明

但是经过我测试,在mybaits执行的时候,没有使用 <![CDATA[>]]> 直接 >=也没有提示报错

 where rownum <![CDATA[<=]]> #{end,jdbcType=INTEGER} ) 

1.12、一个条件参数匹配多个 字段

<if test="userParam != null and userParam != ''">
    AND (t.userId = #{userParam}
          OR a.nickName LIKE CONCAT('%',#{userParam},'%' )
          OR b.realName LIKE CONCAT('%',#{userParam},'%' )
          OR c.realName LIKE CONCAT('%',#{userParam},'%' )
          OR t.customerId LIKE CONCAT('%',#{userParam},'%' )
          OR t.customerName LIKE CONCAT('%',#{userParam},'%'))
</if>

1.13、多条件排序

1.13.1、正确的多条件排序,排序字段由前端进行传入${order}
    <if  test="order != null">
        order by  ${order}
    </if>
 
1.13.2、chose where进行判断

举例:订单降序 1,订单升序 2 ,成交额降序 3,成交额升序 4,

<select id="findCouponTaoKeDataByParam" resultType="com.duodian.youhui.data.coupon.CouponTaoKeItemGoodSummaryData">
  SELECT c.itemTitle,
    COUNT(c.itemId) as orderSize,
    sum(c.estimateAmount) AS sumEstimateAmount ,
    c.adzoneName,c.adzonePid,
    c.createTime,c.itemId  
    FROM  coupon_taoke_data c
    <where>
        c.dataType = 1 and  c.status = 1
        <include refid="findCouponTaoKeDataByParamSQL"></include>
    </where>
    GROUP by c.itemId,c.adzonePid
    <if test="order != null">
        <choose>
            <when test="order == 1">
                order by    orderSize DESC
            </when>
            <when test="order == 2">
                order by    orderSize asc
            </when>
            <when test="order == 3">
                order by   sumEstimateAmount DESC
            </when>
            <when test="order == 4">
                order by   sumEstimateAmount asc
            </when>
        </choose>
    </if>
    <if test="offset != null and limit != ''">
        limit #{offset}, #{limit}
    </if>
</select>

1.13.3、给排序添加非空条件

使用order by orderid desc实现降序时 ,orderid 为null数据的会排在数据的最后面;

但是,order by orderid升序时,orderid 为null的数据则会排在最前面 ,如果想要将orderid为null的数据排在最后,就需要加上is null

select * from b_programme u order by u.orderid is null
1.13.4、自定义排序规则
order by  field (c.status,'Ready','Part','Completed','Close')

1.14 、参数为0,判断null

id传值为0时(前提是id对应的类型为long 或者 Integer,String型无此问题),发现并没有执行if里的sql,因为在mybatis中会自动把0当成‘’空字符串

使用时增加多一个or status == 0判断

<if test="status != null and status !=  '' or status == 0">

1.15、 #和$项目中使用的区别

1.15.1、解释

{变量名} 可以进行预编译、类型匹配等操作,#{变量名}会转化为jdbc的类型
${变量名} 不进行数据类型匹配,直接替换。

select * from tablename where id = #{id}


假设id的值为12  
如果id为字符型,那么#{id}表示的就是'12'  
如果id为整型,  那么#{id}表示的就是12 


select * from tablename where id = ${id}  

如果字段id为整型,sql语句就不会出错,但是如果字段id为字符型, 那么sql语句应该写成select * from table where id = '${id}'。
1.15.2、使用
  • #方式能够很大程度防止sql注入。因为#会自动转换,而&为直接替换,所以$方式无法防止sql注入

  • 项目中的使用,尽量使用# ,少用& 臭小子,明白了吧

#适用于普通的参数传入

$方式一般用于传入数据库对象,例如传入表名。

order为 A ASC, A DESC ,B DESC ,B asc数据,这里直接使用#是错误的

 <when  test="order != null">
          order by  ${order}
</when>

总结:mytabis常见错误

1、mybatis日期报错

异常:invalid comparison: java.util.Date and java.lang.String。
<if test="date!= null and date !=''">
date为Date类型,不能和‘’比较,只判断是不是null就行啦:

<if test="date!= null">

2、函数

2.1、ifnull (如果为空返回第二个,如果不空返回第一个)

ifnull(b.realName,c.realName) authName,

2.2、delete删除的正确方法

1,delete from user as u where u.userid=6; 错误

2,delete from user u where u.userid=6; 错误

3,delete from user where userid=6;  正确

4,delete u.* from user u where u.userid=6; 正确

5,delete u from user u where u.userid=6; 正确 

2.3、group_concat:语句将某一列的值查询成逗号分隔的字符串

select GROUP_CONCAT(c.id) from coupon_item_good;

返回结果
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,32,33

2.4、find_in_set 查询字段为逗号隔开的字段属性

字段 pnum为逗号隔开的字符串

1,2,3,4,21,9

select * from test  t where find_in_set(2,t.pnum) ;

2.5、随机查询

2.5.1 、rand() 性能比较差

RAND() 函数返回的是一个小于1的随机数

BY RAND() LIMIT 1

<select id="getUrl" resultType="java.lang.String">
        SELECT c.url FROM coupon_item_good  5 order by rand() limit 1
</select>

2.5.2、round() 进行优化

SELECT round(column_name,decimals) FROM table_name
参数 描述
column_name 必需。要舍入的字段
decimals 非必需,规定返回的小数位数,如果不给值,则自动四舍五入取整取整,select round(100.9) ; 101

随机选择一个id,然后选择一个大于他的数据,limit控制为1
随机选择一个推广位,具体条件就是下面and中连接的and t1.status 开始

<select id="findUserCouponAdzone" resultType="com.duodian.coupon.CouponAdzone">

        SELECT *
        FROM `coupon_adzone` AS t1
        JOIN (SELECT ROUND(RAND() * (SELECT MAX(id)
                                       FROM `coupon_adzone`)
              ) AS id) AS t2
        WHERE t1.id >= t2.id 
        and t1.status = 1 
        AND  t1.adzoneType = 3  
        and 
        ORDER BY t1.id ASC
        LIMIT 1;
</select>

2.6、case when (试着和if进行替换使用)

2.6.1、普通使用

 case cp.ssid when 'aa' 
 				then '0' 
 				else'1' 
 			 end as flag 

2.6.2、复杂条件

以下场景 我们要扣减金额 operateMoney ,并且要求分配额度和临时额度扣减完成必须大于 0
字段说明:
分配额度 allot_amount
临时额度 temp_amount
总额度 total_amount

总额度直接减去total_amount
判断临时额度是否 大于等于 扣减的额度,
如果大于,那么直接扣减临时额度,分配额度不变
如果小于,则是先扣减临时额度,然后再扣减分配额度
使用主键进行更新,只锁一行,当id和 当分配额度和临时额度扣减后是否大于0 成立的时候更新


update scf_risk_department_limit set
total_amount = total_amount -  #{operateMoney,jdbcType=DECIMAL},
available_amount = available_amount -  #{operateMoney,jdbcType=DECIMAL},
allot_amount = ( 
    case when   temp_amount  >=   #{operateMoney,jdbcType=DECIMAL} 
    then allot_amount   
          else allot_amount -  (  #{operateMoney,jdbcType=DECIMAL} - temp_amount )    
     end ),
temp_amount =  ( 
    case when  temp_amount  >=  #{operateMoney,jdbcType=DECIMAL}  
   	     then temp_amount -  #{operateMoney,jdbcType=DECIMAL}  
         else  0 
    end )
where id =  #{id,jdbcType=BIGINT} 
       and (allot_amount + temp_amount ) >  #{operateMoney,jdbcType=DECIMAL}

2.6.3、case 中 when和and一起使用

update driver_online 
set vRemainCapacity =  case when (vRemainCapacity>0) and ((vRemainCapacity-0.5) >0) 
then vRemainCapacity-0.5  
else 0 end  
where driverId = 'DR120161118100001'

2.6.4、case when 多个条件

update goods
set price = (
case 
  when price between 0 and 99 then price * 1.2
  when price between 100 and 999 then price * 1.1
  when price between 1000 and 1999 then price * 1.05
  when price > 1999 
  then price * 1.02
end);
select * from goods;

2.6.5、case的目标 中添加函数

select substr(t1.area_id, 1, 1) type,
       substr(t1.area_id, 2) id,
       case substr(t1.area_id, 1, 1)
         when 'c' then
          (select t2.country
             from countnumber.dbtable_countryid t2
            where t2.id = substr(t1.area_id, 2))
         else
          (select distinct t3.province
             from countnumber.dbtable_provinceid t3
            where t3.id = substr(t1.area_id, 2))
       end name
  from t_ad_area t1

2.7、If 函数使用

select if( 1 > 0 ,1 ,0 ) ;

IF(expr1,expr2,expr3)

 expr1 是TRUE  返回 expr2 否则返回 expr3

2.8、mysql除法、加法

2.8.1、除法

余数可以为0,得到的结果为NUll

SELECT 1/0 from dual ;

sql大全_长期更新

2.8.2、加法

如果有的参数是null,则可以让参数带上ifNULL,防止null+size造成的数据时null,不显示

select  o.payAmount,
          o.estimateAmount,
         (o3.notValidOrderSize +o.orderSize) as orderSize
from user_info u
        

(IFNULL(o3.notValidOrderSize ,0 ) + IFNULL(o.orderSize ,0 ) ) as orderSize        

2.9、mysql 取小数 convert round cast

2.9.1、convert


select convert(10000,decimal(10,2));

# 四舍五入,decimal(10,2)后面的代表最大长度10以及保留的小数位数2
select convert(10569.3645,decimal(10,2));    #10569.36
select convert(10569.3665555,decimal(10,2)); #10569.37

2.9.2、round

round 第二个表示小数保留几位,不足的补上0。

第二个如果为负数  
-1   代表个位数为0     		ROUND(114.6,-1) 结果 110-2   代表个位数和十分位 为0     ROUND(114.6,-2) 结果  100


ROUND(100.3465,2)  100.35
ROUND(100,2),  	100 
ROUND(0.6,2),	0.60
ROUND(114.6,-1)   110

2.9.3、cast函数:强制转换

select cast(10*1/4 as decimal(18,2)) from dual

2.10、abs函数取绝对值

有时候项目中出现两个数字相减,可能是负数,但是只是需要这连个数的差值,所以就需要用它

ABS( TIMESTAMPDIFF(MINUTE,i.cdate,#{createTime}) ))< #{adzoneTime})

2.11、isnull、length 函数:判断是否为null或空字符串

isnull(aBegBalRule) || length (trim(aBegBalRule))<1

2.12、清表(不要用delete)

delete删除之后还会占用id,

truncate  table_name ; 

2.13、拼接字符串

2.13.1、concat:普通拼接

如果有一个参数为null,则返回结果为null

SELECT CONCAT(’My’, NULL, ‘QL’);

NULL 

2.13.2、concat_ws,分隔符连接字符串

第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。

  • 如果分隔符为 NULL,则结果为 NULL
  • 函数会忽略任何分隔符参数后的 NULL 值。
SELECT CONCAT_WS(',','First name','Second name','Last Name');

First name,Second name,Last Name
SELECT CONCAT_WS(',','First name','','Last Name');

First name,,Last Name (空字符串不会忽略)
SELECT CONCAT_WS(',','First name',null ,'Last Name');

First name,Last Name

2.13.3、使用

模糊查询使用concat('%',#{params},'%'))

<if test="params != null and params != ''">
   u.nickName like  concat('%',#{params},'%')
</if>             

2.14、locate: 出现的index位置

SELECT LOCATE('bar', 'foobarbar'); #4

SELECT LOCATE('xbar', 'foobarbar'); #0

位置从4开始数起 
SELECT LOCATE('bar', 'foobarbar',4); # 4

项目使用

查找具有http字段的用户

select * from users where locate('http',itemUrl);


判断site表中的url是否包含'http://'子串,如果不包含则拼接在url字符串开头
update site set url =concat('http://',url) where locate('http://',url)=0;

2.15、like 匹配

2.15.1、_:表示任意单个字符。匹配单个任意字符

sql大全_长期更新

2.15.2、[charlist] :只要在里面存在就匹配

sql大全_长期更新

2.16、日期的一些函数使用

2.16.1、date_format 、str_to_date

date类型默认的时分秒 为00:00:00

数据准备
create table date_test(
  id bigint(20) not null auto_increment ,
  name varchar(20) default  '',
  yyyyMMdd date  default null ,
  yyyyMMddHHmmss datetime default  null ,
  primary key (id)
)

INSERT INTO date_test (id, name, yyyyMMdd, yyyyMMddHHmmss) VALUES (1, 'healerjean', '2018-12-12', '2018-12-12 23:11:11');
1、date_format

# yyyyMMddHHmmss 存储数据为  2018-12-12 23:11:11
select * from date_test d where date_format(d.yyyyMMddHHmmss,"%Y-%m-%d") = '2018-12-12';
select * from date_test d where date_format(d.yyyyMMddHHmmss,"%Y-%m-%d %H:%i:%s") = '2018-12-12 23:11:11';


# yyyyMMdd 存储的为 2018-12-12
select * from date_test d where date_format(d.yyyyMMdd,"%Y-%m-%d") = '2018-12-12';
select * from date_test d where date_format(d.yyyyMMdd, "%Y-%m-%d %H:%i:%s") = '2018-12-12 00:00:00';

2、str_to_date
select str_to_date('08/09/2008', '%m/%d/%Y'); -- 2008-08-09
select str_to_date('08/09/08' , '%m/%d/%y'); -- 2008-08-09
select str_to_date('08.09.2008', '%m.%d.%Y'); -- 2008-08-09
select str_to_date('08:09:30', '%h:%i:%s'); -- 08:09:30
select str_to_date('08.09.2008 08:09:30', '%m.%d.%Y %h:%i:%s'); -- 2008-08-09 08:09:30



#注意哦,下面这种我们匹配数据库中一定存在的,不可以类似于format那样模糊查询,因为条件是我们字数输入的
select * from date_test d where d.yyyyMMdd = STR_TO_DATE('2018-12-12','%Y-%m-%d') ;
select * from date_test d where d.yyyyMMdd = STR_TO_DATE('2018-12-12 00:00:00','%Y-%m-%d %H:%i:%s') ;


select * from date_test d where (d.yyyyMMdd) = '2018-12-12'; 
# 下面这个找不到数据,说明date类型默认的时分秒 为00:00:00
select * from date_test d where date_format(d.yyyyMMdd, "%Y-%m-%d %H:%i:%s") = '2018-12-12 11:00:00';

2.16.2、timestampdiff :选择大于或小于某个时间段的数据

单位 说明
SECOND
MINUTE 分钟
HOUR 小时
DAY
MONTH
YEAR
2.16.2.1、计算日期差
计算日期差,不要使用now()而是使用 curdate() ;
TIMESTAMPDIFF(DAY, curdate(),cb.bill_end_time) as warning_day,
2.16.2.2、计算小时差
获取48小时之内的数据

<select id="find48Hours"  resultType="com.duodian.OnlineChatPerson">
	SELECT  * from  call_online_chat_person c
    WHERE timestampdiff(HOUR,c.cdate,now())  < 48 
</select>

2.16.3、unix_timestamp:获取日期的时间戳

unix_timestamp(),
unix_timestamp(date),
from_unixtime(unix_timestamp),
from_unixtime(unix_timestamp,format)

select unix_timestamp(); -- 1218290027
select unix_timestamp('2008-08-08'); -- 1218124800
select unix_timestamp('2008-08-08 12:30:00'); -- 1218169800


SELECT  unix_timestamp(u.date) from user_info u;

1528427765000 毫秒

2.16.4、from_unixtime : 时间戳转化为日期(时间戳为毫秒)

select from_unixtime(1218290027); -- '2008-08-09 21:53:47'
select from_unixtime(1218169800, '%Y %D %M %h:%i:%s %x'); -- '2008 8th August 12:30:00 2008'


SELECT from_unixtime(1500109248, '%Y-%m-%d %H:%i:%S');
2017-07-15 17:00:48

2.16.5、date_add 、date_sub:日期加减计算

date_add(date,INTERVAL expr type)
date_sub(date,INTERVAL expr type)

"OrderDate" 添加 2SELECT 
OrderId,
date_add(OrderDate,INTERVAL 2 DAY) AS OrderPayDate
FROM Orders


MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
SECOND_MICROSECOND
MINUTE_MICROSECOND
MINUTE_SECOND
HOUR_MICROSECOND
HOUR_SECOND
HOUR_MINUTE
DAY_MICROSECOND
DAY_SECOND
DAY_MINUTE
DAY_HOUR
YEAR_MONTH

2.16.6、 to_days(date), from_days(days) :(日期、天数(互转))

select to_days('0000-00-00'); -- 0
select to_days('2008-08-08'); -- 733627

2.16.7、time_to_sec(time), sec_to_time(seconds) (时间、秒(互转))

select time_to_sec('01:00:05'); -- 3605
select sec_to_time(3605); -- '01:00:05'

2.16.8、 makdedate(year,dayofyear), maketime(hour,minute,second) (拼凑日期、时间函数:)

select makedate(2001,31); -- '2001-01-31'
select makedate(2001,32); -- '2001-02-01'
select maketime(12,15,30); -- '12:15:30'

2.16.9、查询一些特定日期

今天  
select * from 表名 where to_days(时间字段名) = to_days(now());  

昨天  
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1  

7SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)30SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)  

本月  
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )  

上一月  
SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时间字段名, '%Y%m' ) ) =1  

#查询本季度数据  
select * from `ht_invoice_information` where quarter(create_date)=quarter(now());  

#查询上季度数据  
select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(DATE_SUB(now(),interval 1 QUARTER));  

#查询本年数据  
select * from `ht_invoice_information` where YEAR(create_date)=YEAR(NOW());  

#查询上年数据  
select * from `ht_invoice_information` where year(create_date)=year(date_sub(now(),interval 1 year));  

查询当前这周的数据   
SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) 
= YEARWEEK(now());  

查询上周的数据  
SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now())-1;  

查询当前月份的数据  
select name,submittime from enterprise   where date_format(submittime,'%Y-%m')=date_format(now(),'%Y-%m')  

查询距离当前现在6个月的数据  
select name,submittime from enterprise where submittime between date_sub(now(),interval 6 month) and now();

2.16.10、其他

https://www.cnblogs.com/ggjucheng/p/3352280.html

3、表相关

3.1、添加表的备注和字段备注

3.1.1、创建表的时候添加备注

CREATE TABLE `healerjean_comment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '名字备注',
  `email` varchar(64)  NOT NULL,
  `message` text ,
  PRIMARY KEY (`id`),
  KEY `index_name` (`name`)
)  COMMENT='表名备注' ;

3.1.2、表创建完成添加表名备注和字段备注

ALTER TABLE healerjean_comment COMMENT='测试索引表';

ALTER table healerjean_comment MODIFY name  VARCHAR(32) NOT NULL COMMENT '名字备注'

3.2、查询建表语句

show create table table_name ;

sql大全_长期更新

3.3、查看列的属性

show full columns from healerjean;

sql大全_长期更新

3.4、修改字段顺序

3.4.1、放到第1位

alter table demo_entity modify name varchar(32) comment '名字' first ;

3.4.2、放到某个字段后面

alter table demo_entity modify name varchar(32) comment '名字' after id  ;

3.5、给表添加约束(唯一索引)

这个其实很常见,经常我们会使用主键作为唯一约束,如果是手机用户,或者是邮箱用户进行登录,那么这个登录的字段并不是主键。在高并发,注册的时候,如果不设置唯一约束,则可能会导入两个相同的数据。为了防止这种情况发生,我们要注意添加约束。

创建联合约束,我们发现,这里设置为唯一约束,建立唯一约束和唯一索引又什么区别?建立唯一约束的时候,也会自动的创建唯一索引。建立唯一索引可以说是唯一约束的一种手段。

3.5.1、添加普通和唯一索引

DROP  TABLE  user_info ;
create table user_info(
  id BIGINT(20) not null auto_increment,
  fuWuBusinessNoId  BIGINT(20) default null,
  dingYueBusinessNoId  BIGINT(20) default null,
  openId varchar(20) DEFAULT  NULL  UNIQUE  ,
  iphone varchar(20) default null COMMENT '',
  status int(11) default null ,
  cdate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  udate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY unique_fuWuBusinessNoId_iphone (fuWuBusinessNoId,iphone) COMMENT '服务号和手机号唯一标识一个用户,可用于手机号登录判断',
  PRIMARY key (id));

添加普通索引
ALTER TABLE  user_info add name VARCHAR(20) DEFAULT  NULL  ;
CREATE INDEX  index_name  on user_info(name)  ;

添加唯一索引
ALTER TABLE  user_info add mail VARCHAR(20) DEFAULT  NULL  ;
CREATE UNIQUE INDEX  index_mail  on user_info(mail)  ;

alter table user_inf add unique index_mail `user_info` ( mail); 

3.5.2、查看索引

show INDEX  from  user_info ;

3.5.1、删除约束(唯一索引)

 
 ALTER TABLE jw_role DROP INDEX resource_name;

3.5.4、SpringBoot注解


@Table(name = "user_info",
uniqueConstraints = {
        @UniqueConstraint(columnNames = "openId"), 
        @UniqueConstraint(columnNames = {"fuId","iphone"})},
indexes = {
    @Index(name = "index_itemGoodId",columnList = "authority,permission",unique = true),
    @Index(name = "index_cdate",columnList = "cdate")
})
            
      
        
@Entity
@Accessors(chain = true)
@Data
@NoArgsConstructor
@ApiModel(description = "微信用户信息")
public class UserInfo {

3.6、存储引擎

3.6.1、show engines:查看存储引擎

mysql> SHOW  ENGINES  ;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.05 sec)

3.6.1、修改表的存储引擎

alter table  healerjean_comment ENGINE  = MyISAM ;

3.6.2、查看表的存储引擎

show  create  table table_name ;

复杂查询

1、count

1.1、count(*)、count(id)

如果版本不太高的会报错*(因为没有分组),高级的版本下面这个只会输出一行

SELECT  count(*) as "count",idfa from apps_click_record a; 

1.2、和group分组一起使用 ,就表示分组之后每组的个数

SELECT  count(*) as "count",idfa 
from apps_click_record a 
WHERE  a.keywordId = '169995' 
GROUP  by idfa 
ORDER BY count(*) DESC ;
    

1.3、count(*) 和 * 的查询 是错误的

下面是错误的

SELECT  count(*) as "count",* from apps_click_record a; 

1.4、count(distinct Sname)去掉重复得到唯一的数量

select count(distinct b.type) from B b  

# 下面这种写法垃圾死了 
select count(*) from 
(
    select b.type from B b group by b.type
) m

2、Group by

5.7 版本的 mysql中可能会遇到取唯一值的问题。一定要注意

2.1、分组过滤重复

2.1.1、表中有id和name 两个字段,查询出name重复的所有数据
select * 
from healerjean a 
where (a.username) in (
                    select username 
                    from healerjean 
                    group by username 
                             having count(*) > 1
                    )

2.1.2、删除分组中重读的数据,只保留id最小的记录

1、查询每组重复的用户名

select username from healerjean group by username having count(username) > 1

2、先查询每组重复的id最小的数据

select min(id)   from healerjean group by username having count(username)>1

3、判断用户名重复,并排除掉id最小的数据,进行删除


delete from healerjean 
where username in (
                    select username 
                    from healerjean 
                    group by username 
                    having count(username) > 1
                    )
      and id not in (
                    select min(id)  
                    from healerjean 
                    group by username 
                    having count(username)>1)
2.1.3、查找表中多余的重复记录(多个字段)
select * 
from vitae a
where (a.peopleId,a.seq) in (
                            select peopleId, seq      
                            from vitae 
                            group by peopleId,seq 
                            having count(*) > 1)

2.2、havaing count用法

2.2.1、举例说明1
数据样例
create table tb_grade (
  Sno int(11) default 0 comment '学号',
  Sname varchar(20) default '' comment '姓名',
  Cno int(11) default  0  comment '学号',
  Cname varchar(20) default ''comment '课程名',
  score int(11) default 0 comment '分数'
) comment '成绩表' ;

INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1001, '李菲', 1, '语文', 86);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1001, '李菲', 2, '数学', 50);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1001, '李菲', 3, '英语', 41);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1001, '李菲', 4, '化学', 89);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1001, '李菲', 5, '物理', 20);

INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1002, '张宇晋', 1, '语文', 86);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1002, '张宇晋', 2, '数学', 50);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1002, '张宇晋', 3, '英语', 70);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1002, '张宇晋', 4, '化学', 89);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1002, '张宇晋', 5, '物理', 20);


INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1003, '翠花', 1, '语文', 10);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1003, '翠花', 2, '数学', 20);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1003, '翠花', 3, '英语', 70);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1003, '翠花', 4, '化学', 40);
INSERT INTO tb_grade (Sno, Sname, Cno, Cname, score) VALUES (1003, '翠花', 5, '物理', 10);

Sno Sname Cno Cname score
1001 李菲 1 语文 86
1001 李菲 2 数学 50
1001 李菲 3 英语 41
1001 李菲 4 化学 89
1001 李菲 5 物理 20
1002 张宇晋 1 语文 86
1002 张宇晋 2 数学 50
1002 张宇晋 3 英语 70
1002 张宇晋 4 化学 89
1002 张宇晋 5 物理 20
1003 翠花 1 语文 10
1003 翠花 2 数学 20
1003 翠花 3 英语 70
1003 翠花 4 化学 40
1003 翠花 5 物理 10
1、查询不及格科目数大于等于2的学生学号和学生姓名:
select t.Sno,t.Sname 
       from tb_grade t 
where t.score < 60 
group by t.Sno having count(t.Cno) > 2
Sno Sname
1001 李菲
1003 翠花
2、查询不及格科目数大于等于2的学生学号和不及格科目数量:
select t.Sno,
     count(t.Cno) as '不及格科目数量' 
from tb_grade t 
where t.score < 60 
group by t.Sno having count(t.Cno) > 2 
Sno 不及格科目数量
1001 3
1003 4
3、查询不及格科目数大于等于2的学生学号、学生姓名、科目号、科目名称和分数,并按学号降序、科目号升序排序
select t.Sno, 
		t.Sname, 
		t.Cno, 
		t.Cname, 
		t.score
from tb_grade t
where t.score < 60
  and t.Sno in (select b.Sno 
                from tb_grade b 
                where b.score < 60 group by b.Sno having count(b.Cno) > 2)
order by t.Sno desc, Cno asc;
Sno Sname Cno Cname score
1003 翠花 1 语文 10
1003 翠花 2 数学 20
1003 翠花 4 化学 40
1003 翠花 5 物理 10
1001 李菲 2 数学 50
1001 李菲 3 英语 41
1001 李菲 5 物理 20

2.3、having中添加and

接上面的举例说明1的数据样例

select t.Sno,t.Sname
from tb_grade t
where t.score < 60
group by t.Sno having count(t.Cno) > 1 and Sname = '李菲';

Sno Sname
1001 李菲

3、join连接

3.1、内连接 左链接,右连接,全连接

3.1.1、INNER JOIN 和 JOIN
  • **返回左表和 右表同时存在的行 **
  • 和from 直接查询两个表示一样的效果,只不过from这种方式正在被弃用

sql大全_长期更新

 
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
       INNER JOIN Orders ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName

sql大全_长期更新

3.1.2、LEFT JOIN

即使右表中没有匹配,也从左表返回所有的行

select Persons.LastName, Persons.FirstName, Orders.OrderNo
from Persons
       left join Orders on Persons.Id_P = Orders.Id_P
order by Persons.LastName

sql大全_长期更新

sql大全_长期更新

3.1.3、RIGHT JOIN:

即使左表中没有匹配,也从右表返回所有的行

select Persons.LastName, Persons.FirstName, Orders.OrderNo
from Persons
       right join Orders on Persons.Id_P = Orders.Id_P
order by Persons.LastName

sql大全_长期更新

sql大全_长期更新

3.1.4、FULL JOIN:

只要其中一个表中存在匹配,就返回行

select Persons.LastName, Persons.FirstName, Orders.OrderNo
from Persons full
       join Orders on Persons.Id_P = Orders.Id_P
order by Persons.LastName

sql大全_长期更新

sql大全_长期更新

3.2、举例说明1

数据样例
create table department (
  dept_id int(11) default 0 comment '部门id',
  dept_name varchar(20) default '' comment '部门名称'
)comment ='部门' ;

insert into department values(1,'广告部');
insert into department values(2,'媒体部');
insert into department values(3,'管理部');
select * from department ;


create table employee (
  emp_id int(11) default 0 comment '员工id',
  emp_name varchar(20) default '' comment '员工名字',
  dept_id int(11) default 0 comment '部门id',
  emp_wage decimal(19,2) default 0 comment '薪水'
)comment ='员工表' ;


INSERT INTO  VALUES (1, '乔峰', 1, 17000.00);
INSERT INTO  VALUES (2, '张三丰', 1, 15000.00);
INSERT INTO  VALUES (3, '段誉', 2, 18000.00);
INSERT INTO  VALUES (4, '虚竹', 2, 12000.00);
INSERT INTO  VALUES (5, '杨过', 3, 16000.00);
INSERT INTO  VALUES (6, '黄老邪', 1, 17000.00);
INSERT INTO  VALUES (7, '黄蓉', 1, 15000.00);
INSERT INTO  VALUES (8, '郭靖', 2, 15000.00);
INSERT INTO  VALUES (9, '金龙法王', 3, 15000.00);
INSERT INTO  VALUES (10, '老顽童', 3, 11000.00);

dept_id dept_name
1 广告部
2 媒体部
3 管理部
emp_id emp_name dept_id emp_wage
1 乔峰 1 17000.00
2 张三丰 1 15000.00
6 黄老邪 1 17000.00
7 黄蓉 1 15000.00
3 段誉 2 18000.00
4 虚竹 2 12000.00
8 郭靖 2 15000.00
5 杨过 3 16000.00
9 金龙法王 3 15000.00
10 老顽童 3 11000.00
1、left join
select
	d.dept_id,
	d.dept_name,
	e.emp_name,
	e.emp_wage 
from
	department d
	left join employee e on e.dept_id = d.dept_id ;
dept_id dept_name emp_name emp_wage
1 广告部 张宇晋 17000.00
1 广告部 张三丰 15000.00
2 媒体部 张翠 18000.00
2 媒体部 林徽因 12000.00
3 管理部 赵国强 17000.00
2、left join on and

先会在副表中对and条件进行过滤,然后再跟左边主表进行关联

  • 主表 (只会对副表起作用)
select d.dept_id,
       d.dept_name,
       e.emp_name,
       e.emp_wage
from department d
       left join employee e on e.dept_id = d.dept_id and d.dept_id = 1
dept_id dept_name emp_name emp_wage
1 广告部 乔峰 17000.00
1 广告部 张三丰 15000.00
1 广告部 黄老邪 17000.00
1 广告部 黄蓉 15000.00
2 媒体部 NULL NULL
3 管理部 NULL NULL
  • 副表(只会对副标起作用)
select d.dept_id,
       d.dept_name,
       e.emp_name,
       e.emp_wage
from department d
       left join employee e on e.dept_id = d.dept_id and e.emp_wage = 17000
dept_id dept_name emp_name emp_wage
1 广告部 乔峰 17000.00
1 广告部 黄老邪 17000.00
2 媒体部 NULL NULL
3 管理部 NULL NULL
3、where实现全部查询结果的过滤
select d.dept_id,
       d.dept_name,
       e.emp_name,
       e.emp_wage
from department d
       left join employee e on e.dept_id = d.dept_id
where e.emp_wage = 17000;
dept_id dept_name emp_name emp_wage
1 广告部 乔峰 17000.00
1 广告部 黄老邪 17000.00
4、进阶sql
1、求每个部门中的最大工资和最小工资
  • 求各个部门的最大工资 和最小工资
select e.dept_id,
       max(emp_wage) as max_exp_wage,
       min(emp_wage) as min_exp_wage
from employee e
group by e.dept_id 
dept_id max_exp_wage min_exp_wage
1 17000.00 15000.00
2 18000.00 12000.00
3 16000.00 11000.00
  • 上面的查询已经知道部门的最大工资和最小工资了,但是部门的名称还没有查出来,可以关联查出部门的名称(因为是一一对应,所以join查询可以满足)
select d.dept_id,
       d.dept_name,
       s.max_exp_wage,
       s.min_exp_wage
from department d
       left join (
              select e.dept_id,
                     max(emp_wage) as max_exp_wage,
                     min(emp_wage) as min_exp_wage
              from employee e
              group by e.dept_id
            ) s on s.dept_id = d.dept_id;
dept_id dept_name max_exp_wage min_exp_wage
1 广告部 17000.00 15000.00
2 媒体部 18000.00 12000.00
3 管理部 16000.00 11000.00
2、查询每个部门中最大工资雇员并按照部门排序

需要考虑的是,部门中肯定有工资相同的,那么最大工资也肯定有可能会相同,所以肯定主表是employee

  • 1、先查询每个部门最大的工资
select e.dept_id, 
		max(e.emp_wage) as max_exp_wage
from employee e
group by e.dept_id
dept_id max_exp_wage
1 17000.00
2 18000.00
3 16000.00
  • 2、查询工资是最大工资的雇员
select em.dept_id,
       em.emp_id,
       em.emp_name,
       em.emp_wage
from employee em
        join (select e.dept_id, max(emp_wage) as max_exp_wage from employee e group by e.dept_id) s
                 on s.dept_id = em.dept_id
where em.emp_wage = s.max_exp_wage
order by em.dept_id

dept_id emp_id emp_name emp_wage
1 1 乔峰 17000.00
1 6 黄老邪 17000.00
2 3 段誉 18000.00
3 5 杨过 16000.00
  • 3、上面基本上完事了,就差部门没出来,所以关联查询部门即可
select em.dept_id,
       de.dept_name,
       em.emp_id,
       em.emp_name,
       em.emp_wage
from employee em
       join department de on de.dept_id = em.dept_id
       join (select e.dept_id, max(emp_wage) as max_exp_wage from employee e group by e.dept_id) s
            on s.dept_id = em.dept_id
where em.emp_wage = s.max_exp_wage
order by em.dept_id
dept_id dept_name emp_id emp_name emp_wage
1 广告部 6 黄老邪 17000.00
1 广告部 1 乔峰 17000.00
2 媒体部 3 段誉 18000.00
3 管理部 5 杨过 16000.00
3、查询大于平均工资的雇员,并按照部门排序
  • 1、先查询各个部门的平均工资
select e.dept_id, avg(e.emp_wage)
from employee e
group by e.dept_id;
dept_id AVG(e.emp_wage)
1 16000.000000
2 15000.000000
3 14000.000000
  • 2、查询工资大于平均工资的雇员,这个时候需要left join(join都可以,因为肯定是一一对应的关系)查询雇员表了
select em.dept_id, 
		s.avg_wage, 
		em.emp_id, 
		em.emp_name, 
		em.emp_name,
        em.emp_wage
from employee em
       left join (select e.dept_id, 
                  		  avg(e.emp_wage) as avg_wage 
                  from employee e group by e.dept_id)
                  s on s.dept_id = em.dept_id
where em.emp_wage > s.avg_wage
order by em.dept_id;
dept_id avg_wage emp_id emp_name emp_name emp_wage
1 16000.000000 1 乔峰 乔峰 17000.00
1 16000.000000 6 黄老邪 黄老邪 17000.00
2 15000.000000 3 段誉 段誉 18000.00
3 14000.000000 5 杨过 杨过 16000.00
3 14000.000000 9 金龙法王 金龙法王 15000.00
  • 3、其实上面的结果已经完事了,就是部门名字没出来
select em.dept_id, 
		d.dept_name, 
		s.avg_wage, 
		em.emp_id, 
		em.emp_name, 
		em.emp_wage
from employee em
       join department d on d.dept_id = em.dept_id
       join (select e.dept_id, 
             		avg(e.emp_wage) as avg_wage 
             from employee e group by e.dept_id) 
             s on s.dept_id = em.dept_id
where em.emp_wage > s.avg_wage
order by em.dept_id;
dept_id dept_name avg_wage emp_id emp_name emp_wage
1 广告部 16000.000000 6 黄老邪 17000.00
1 广告部 16000.000000 1 乔峰 17000.00
2 媒体部 15000.000000 3 段誉 18000.00
3 管理部 14000.000000 5 杨过 16000.00
3 管理部 14000.000000 9 金龙法王 15000.00

4、union和 union all 操作符

1、select语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

2、默认情况下 union操作符已经删除了重复数据。如果允许重复的值,请使用 UNION ALL。


SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2

5、distinct:必须放在开头

数据样例

create table `test_table`
(
       `id`      int(11)     default '0' comment 'id',
       `english` varchar(20) default '' comment 'name',
       `age`     int(11)     default 0
) 


INSERT INTO test_table (id, english, age) VALUES (1, 'a', 12);
INSERT INTO test_table (id, english, age) VALUES (2, 'b', 12);
INSERT INTO test_table (id, english, age) VALUES (3, 'c', 13);
INSERT INTO test_table (id, english, age) VALUES (4, 'c', 16);
INSERT INTO test_table (id, english, age) VALUES (5, 'b', 12);
id english age
1 a 12
2 b 12
3 c 13
4 c 16
5 b 12

5.1、 只作用于一个字段

select distinct english from test_table ;
name
a
b
c

5.2、作用于2个字段 :必须得id与name都相同的才会被排除

select distinct english, age from test_table  ;

可以观察到排除一个 b 12 
english age
a 12
b 12
c 13
c 16

5.3、count(distinct colume )

select count(english) from test_table ;

5
select count(distinct english) from test_table


3

5.4、distinct 和 count、group by

select  age, count( english) from test_table group by age ;
age count( english)
12 3
13 1
16 1
select  age, count(distinct english) from test_table group by age ;
age count(distinct english)
12 2
13 1
16 1

感兴趣的,欢迎添加博主微信,

哈,博主很乐意和各路好友交流,如果满意,请打赏博主任意金额,感兴趣的在微信转账的时候,备注您的微信或者其他联系方式。添加博主微信哦。

请下方留言吧。可与博主*讨论哦

支付包 微信 微信公众号
sql大全_长期更新 sql大全_长期更新 sql大全_长期更新
相关标签: Database