网站seo诊断报告例子学做网站的书
### 批量插入
```
 INSERT INTO 表名 (字段列表) VALUES (字段对应的值),(字段对应的值),(字段对应的值),(字段对应的值),
 ```
js 代码示例:
 ```
 function batchAddOrderRecords(recordArr, callBack) {
   callBack = callBack == null ? nop : callBack;
const partSql = 'INSERT INTO shop_order ( order_id, goods_id, user_id, number_all, vip_level, batch_id ) VALUES ';
   // 拼接各行的值
   let partSql1 = '';
  for (let i = 0; i < recordArr.length; i += 1) {
     const one = recordArr[i];
     partSql1 += `('${one.orderId}', ${one.goodsId}, ${one.userId}, ${one.numberAll}, ${one.vipLevel}, ${one.batchId})`;
    if (i + 1 < recordArr.length) {
       partSql1 += ',';
     }
   }
const sql = `${partSql} ${partSql1}`;
  query(sql, (err, rows) => {
     if (err) {
       callBack(null);
     } else {
       callBack(rows.affectedRows > 0);
     }
   });
 }
 ```
### 两个表组合,获得笛卡尔积
 比如 商品表 + 玩家表,我需要获得 每个人对应所有商品的所有记录
```
 SELECT a.*, b.* FROM shop_goods_config a, tbl_user_info b
 ```
###  承接上一个,找出所有vip用户,时间段内,尚未发出的权益列表
 会员lv1,每月1次优先购。会员lv2,每月2次优先购
```
 function getNotSendRightByTime(startTimeStr, endTimeStr, callBack) {
     callBack = callBack == null ? nop : callBack;
    const sql = `SELECT
                     alldata.* 
                 FROM
                 (
                   // 这部分是获取 所有人应该分得的所有 商品权益记录
                     SELECT
                         a.goods_id,
                         b.user_id,
                         a.goods_name,
                         a.vip_level,
                         a.number,
                         a.loop_type,
                         b.user_name,
                         cast( AES_DECRYPT( FROM_BASE64 ( b.mobile ), 'jeo8lD320uu298wF' ) AS CHAR ) AS mobile 
                     FROM
                         // 这里是组合两个表,10 * 10 = 100条记录
                         shop_goods_config a,
                         tbl_user_info b 
                     WHERE
                       // 筛选 vip用户
                         b.vip_level > 0 
                         // 筛选 只保留 比 玩家vip 等级低的商品记录
                         AND b.vip_level >= a.vip_level 
                 ) alldata
                 LEFT JOIN (
                   // 这部分是获取 玩家 本月已发放的记录
                     SELECT
                         user_id,
                         goods_id 
                     FROM
                         shop_order 
                     WHERE
                         user_id IN ( SELECT user_id FROM tbl_user_info WHERE vip_level > 0 ) 
                         AND vip_level > 0 
                         // 限制月份
                         AND create_time >= '${startTimeStr}' 
                         AND create_time <= '${endTimeStr}' 
                 ) senddata 
                 // 这里是 玩家Id+商品Id,确认唯一记录
                 ON alldata.goods_id = senddata.goods_id AND alldata.user_id = senddata.user_id 
                 WHERE
                     // 这里是 筛选 历史记录的,就是没发过的
                     senddata.user_id IS NULL;`;
    query(sql, (err, rows) => {
         if (err) {
             callBack(null);
         } else {
             callBack(rows);
         }
     });
 }
 ```
### 递归查找我的上级
表名: tbl_user_invite
 我的邀请码字段: invite_code
 我的上级邀请码字段: parent_invite_code
 参数,就是我的邀请码 : aaaaaaaa
 ```
 SELECT
     lv,
     user_id,
     invite_code,
     parent_invite_code 
 FROM
     (
     SELECT
         @r AS _id,
         @l := @l + 1 AS lv,
         ( SELECT @r := parent_invite_code FROM tbl_user_invite WHERE invite_code = _id LIMIT 1 ) AS parent_id 
     FROM
         ( SELECT @r := 'aaaaaaaa', @l := 0 ) vars,
         tbl_user_invite h 
     ) T1
     JOIN tbl_user_invite T2 ON T1._id = T2.invite_code 
 GROUP BY
     invite_code 
 ORDER BY
     lv;
 ```
 ### 递归查找我的下级,各层级都有谁
表名: tbl_user_invite
 我的邀请码字段: invite_code
 我的上级邀请码字段: parent_invite_code
 参数,就是我的邀请码 : aaaaaaaa
 ```
 SELECT
 @ids AS _ids,
 ( SELECT @ids := GROUP_CONCAT( invite_code ) FROM tbl_user_invite WHERE FIND_IN_SET( parent_invite_code, @ids ) ) AS cids,
 @l := @l + 1 AS LEVEL 
 FROM
 tbl_user_invite,
 ( SELECT @ids := 'aaaaaaaa', @l := 0 ) b 
 WHERE
 @ids IS NOT NULL
```
### 查询记录时,把时间字段 格式化
```
 SELECT
     DATE_FORMAT( update_time, '%Y-%m-%d %H:%i:%s' ) AS create_time 
 FROM
     tbl_user_info 
 ```
### 汇总玩家战绩
 count + if 根据条件统计条数
 CASE WHEN 根据游戏类型,换算分数
 TO_DAYS 筛选今天。但这个效率偏低,需要数据库试试去计算。 最好还是根据时间字符串,进行范围检索
 ```
 SELECT
                     user_id AS userId,
                     user_name AS userName,
                     head_icon AS headIcon,
                     count( id ) AS gameCount,
                     count(IF( big_win = 1, 1, NULL )) AS bigWinCount,
                     IFNULL(sum(CASE
                         WHEN tab.game_type = 8 
                             OR tab.game_type = 17 
                             OR tab.game_type = 18 
                             OR tab.game_type = 19 
                             OR tab.game_type = 20 
                             OR tab.game_type = 25 
                             OR tab.game_type = 27 
                             OR tab.game_type = 28 
                             OR tab.game_type = 30 
                             OR tab.game_type = 31 
                         THEN
                             tab.score_win / 10 
                         WHEN tab.game_type = 29 
                         THEN
                             tab.score_win / 1000
                         ELSE tab.score_win 
                         END),0) AS scoreAll
                 FROM
                     friends_circle_game_record_card  tab
                 WHERE
                     TO_DAYS(now()) - TO_DAYS( create_time ) = 0
                 GROUP BY
                     user_id
 ```
### 查禁止同桌记录里边,是否有2个玩家的记录
表名: friends_circle_forbid_intab
 字段:user_id_1, user_id_2, user_id_3, user_id_4 
 4个字段用于存放最多限制4个玩家不能出现在同一个桌子内
思路是两个玩家ID, 3025,1261813 再四个字段里边出现的次数,如果出现 2次,则表示该条记录中同时存在 两个玩家(前提是同一条记录,id不能重复) 
 ```
 SELECT count(*) as allCount from 
 (
   SELECT
     // 判断字段 是否出现 两个id,出现则为1
     CASE WHEN  user_id_1 = 3025 OR user_id_1 = 1261813 THEN 1 ELSE 0 END AS find_1,
     CASE WHEN  user_id_2 = 3025 OR user_id_2 = 1261813 THEN 1 ELSE 0 END AS find_2,
     CASE WHEN  user_id_3 = 3025 OR user_id_3 = 1261813 THEN 1 ELSE 0 END AS find_3,
     CASE WHEN  user_id_4 = 3025 OR user_id_4 = 1261813 THEN 1 ELSE 0 END AS find_4
   FROM friends_circle_forbid_intab
 ) a
 // 把四个字段判断的结果相加,看是否大于等于2
 WHERE a.find_1 + a.find_2 + a.find_3 + a.find_4 >= 2;
 ```
### 接上条,根据一个玩家ID,清空记录里边 该玩家的id字段,以及信息字段
技巧就是通过 CASE WHEN THEN  来实现根据字段进行条件判定,并同时进行update操作的效果
 ```
 UPDATE friends_circle_forbid_intab set
 user_info_1 = case when user_id_1 = 3024 then '' else user_info_1 end,
 user_info_2 = case when user_id_2 = 3024 then '' else user_info_2 end,
 user_info_3 = case when user_id_3 = 3024 then '' else user_info_3 end,
 user_info_4 = case when user_id_4 = 3024 then '' else user_info_4 end,
 user_id_1 = case when user_id_1 = 3024 then 0 else user_id_1 end,
 user_id_2 = case when user_id_2 = 3024 then 0 else user_id_2 end,
 user_id_3 = case when user_id_3 = 3024 then 0 else user_id_3 end,
 user_id_4 = case when user_id_4 = 3024 then 0 else user_id_4 end
 where user_id_1 = 3024 or user_id_2 = 3024 or user_id_3 = 3024 or user_id_4 = 3024
 ```
### 存在更新,不存在插入
 ON DUPLICATE KEY
 设计表的时候,设计好 唯一 字段,就可以将 先判定记录是否存在,再插入/更新记录。变成一条sql完成所有
 ### 统计 积分表,按总分排名次,并 插入/更新 到 排行榜表
 排行榜表:
 tchl_game_score_rank
 字段:
 user_id, score, rank
分数表:
 tchl_game_score
 字段:
 user_id, max_score
```
 function createGameRank(callBack) {
     callBack = callBack == null ? nop : callBack;
    const sql = `INSERT INTO tchl_game_score_rank ( user_id, score, rank ) 
                 SELECT
                     a.user_id AS userId,
                     a.max_score AS score,
                     @rk := @rk + 1 AS rank 
                 FROM
                     tchl_game_score a,
                     ( SELECT @rk := 0 ) b 
                 ORDER BY
                     a.max_score DESC,
                     a.user_id
                 ON DUPLICATE KEY UPDATE 
                     user_id = VALUES( user_id ),
                     score = VALUES(score);`;
    query(sql, (err, rows) => {
         if (err) {
             callBack(null);
         } else {
             callBack(rows.affectedRows > 0);
         }
     });
 }
 ```
