mysql开发技巧笔记

行转列

姓名 打怪数
猪八戒 10
猪八戒 2
猪八戒 12
沙僧 3
沙僧 5
沙僧 1
孙悟空 20
孙悟空 10
孙悟空 17
孙悟空 猪八戒 沙僧
47 24 9
SELECT u1.user_name,SUM(kills) FROM user1 u1
JOIN user_kills uk ON u1.id = uk.user_id
GROUP BY u1.user_name;

结果

user_name SUM(kills)
孙悟空 47
沙僧 9
猪八戒 24

使用 SUM 进行 行转列

SELECT * FROM
(
    SELECT SUM(kills) as '沙僧' FROM user1 u JOIN user_kills uk on u.id = uk.user_id AND u.user_name = '沙僧'
)a CROSS JOIN
(
    SELECT SUM(kills) as '猪八戒' FROM user1 u JOIN user_kills uk on u.id = uk.user_id AND u.user_name = '猪八戒'
)b CROSS JOIN
(
    SELECT SUM(kills) as '孙悟空' FROM user1 u JOIN user_kills uk on u.id = uk.user_id AND u.user_name = '孙悟空'
)c

SELECT SUM(case WHEN user_name = '孙悟空' THEN kills END) AS '孙悟空' ,
    SUM(case WHEN user_name = '猪八戒' THEN kills END) AS '猪八戒' ,
    SUM(case WHEN user_name = '沙僧' THEN kills END) AS '沙僧' 
FROM user1 u JOIN user_kills uk ON u.id = uk.user_id
孙悟空 猪八戒 沙僧
47 24 9

列转行

应用场景

  1. 属性拆分
operator_id op_userid permission
1 10001 10070501,13011104,1301105,13010403
operator_id op_userid permission
1 10001 10070501
1 10001 13011104
1 10001 1301105
1 10001 13010403
  1. etl数据处理
user_name mobile
唐僧 12112345678,14112345678,16112345678
猪八戒 12144643321,14144643321
孙悟空 12166666666,14166666666,16166666666,18166666666
沙僧 12198343214,14198343214
user_name mobile
唐僧 12112345678
唐僧 14112345678
唐僧 16112345678

1. 利用序列表处理列转行的数据

id
1
2
3
4
5
6
7
SELECT
    user_name,
    REPLACE (
        SUBSTRING(SUBSTRING_INDEX(mobile, ',', a.id),
        CHAR_LENGTH(SUBSTRING_INDEX(mobile, ',', a.id - 1)) + 1)
        ,',','') AS mobile
FROM
    tb_sequence a
CROSS JOIN (
    SELECT
        user_name,
        CONCAT(mobile, ',') AS mobile,
        LENGTH(mobile) - LENGTH(REPLACE(mobile, ',', '')) + 1 size
    FROM
        user1 b
) b ON a.id <= b.size
user_name mobile
唐僧 12112345678
唐僧 14112345678
唐僧 16112345678

2. 使用union进行列转行

user_name arms clothing shoe
唐僧 九环锡杖 锦襕袈裟 僧鞋
猪八戒 九齿钉耙 僧衣 僧鞋
孙悟空 金箍棒 锁子黄金甲 藕丝步云履
沙僧 降妖宝杖 僧衣 僧鞋
SELECT user_name,'arms' AS equipment,arms AS eq_name
    FROM user1 u JOIN user1_equipment ue ON u.id = ue.user_id
UNION ALL -- union all 如果没有重复 效率更高 
SELECT user_name,'clothing' AS equipment,clothing AS eq_name
    FROM user1 u JOIN user1_equipment ue ON u.id = ue.user_id
UNION ALL 
SELECT user_name,'shoe' AS equipment,shoe AS eq_name
    FROM user1 u JOIN user1_equipment ue ON u.id = ue.user_id
ORDER BY user_name
user_name equipment eq_name
唐僧 arms 九环锡杖
唐僧 clothing 锦襕袈裟
唐僧 shoe 僧鞋

如何在子查询中匹配两个值

常见的子查询使用场景

查询出每一个取经人打怪最多的日期,并列出取经人的姓名,打怪最多的日期和打怪的数量

SELECT u.user_name,uk.timestr,uk.kills as kills FROM user1 u 
JOIN user_kills uk ON u.id = uk.user_id
JOIN (
        SELECT user_id,MAX(kills) AS kills FROM user_kills GROUP BY user_id
    )c ON uk.user_id = c.user_id AND uk.kills = c.kills
user_name timestr kills
猪八戒 2013-02-05 00:00:00 12
沙僧 2013-02-11 00:00:00 5
孙悟空 2013-01-11 00:00:00 20

同一属性多值过滤

使用关联的方式实现多属性查询(1)

查询 user1_skill中 同时具备 skill念经变化的取经人

SELECT u.user_name,s1.skill,s2.skill
FROM user1 u
JOIN user1_skill s1 ON u.id = s1.user_id
JOIN user1_skill s2 ON u.id = s2.user_id
WHERE s1.skill = '念经' AND s2.skill = '变化'
AND s1.skill_level >0 AND s2.skill_level >0

使用关联的方式实现多属性查询(2)

查询 掌握的技能skill 大于等于2的取经人

SELECT u.user_name,s1.skill,s2.skill,s3.skill,s4.skill
FROM user1 u
LEFT JOIN user1_skill s1 ON u.id = s1.user_id AND s1.skill='念经' AND s1.skill_level > 0
LEFT JOIN user1_skill s2 ON u.id = s2.user_id AND s2.skill='变化' AND s2.skill_level > 0
LEFT JOIN user1_skill s3 ON u.id = s3.user_id AND s3.skill='腾云' AND s3.skill_level > 0
LEFT JOIN user1_skill s4 ON u.id = s4.user_id AND s4.skill='浮水' AND s4.skill_level > 0
WHERE 
    (CASE WHEN s1.skill IS NOT NULL THEN 1 ELSE 0 END) +
    (CASE WHEN s2.skill IS NOT NULL THEN 1 ELSE 0 END) +
    (CASE WHEN s3.skill IS NOT NULL THEN 1 ELSE 0 END) +
    (CASE WHEN s4.skill IS NOT NULL THEN 1 ELSE 0 END) >= 2

使用GROUP BY实现多属性查询

SELECT u.user_name
FROM user1 u
JOIN user1_skill s ON u.id = s.user_id
WHERE s.skill IN('变化','念经','腾云','浮水') AND s.skill_level > 0
GROUP BY u.user_name HAVING COUNT(*) >= 2

如何计算累进税问题

  1. 先计算出各个区间 有多少钱需要缴税
SELECT user_name,money,low,high,
LEAST(money - low,high - low) AS curmoney,rate
FROM user1 u JOIN taxrate t ON u.money > t.low
ORDER BY user_name,low
user_name money low high curmoney rate
唐僧 35000.00 0 1500 1500.00 0.03
唐僧 35000.00 1500 4500 3000.00 0.1
唐僧 35000.00 4500 9000 4500.00 0.2
唐僧 35000.00 9000 35000 26000.00 0.25
  1. 将需要缴税部分的钱 乘以 税率
SELECT user_name,SUM(curmoney*rate) money
FROM(
    SELECT user_name,money,low,high,
    LEAST(money - low,high - low) AS curmoney,rate
    FROM user1 u JOIN taxrate t ON u.money > t.low
    ORDER BY user_name,low
) c
GROUP BY user_name
user_name money
唐僧 7745.00
孙悟空 5995.00
沙僧 1045.00
猪八戒 2745.00

mysql生成行号

SELECT
    COUNT(*) AS rowNum,
    E1.first_name
FROM
    employees E1,
    employees E2
WHERE
    E1.first_name >= E2.first_name
GROUP BY
    E1.emp_no

SELECT
    (@rowNum :=@rowNum + 1) AS rowNum,
    first_name
FROM
    employees,
    (SELECT(@rowNum := 0)) num
ORDER BY
    first_name DESC
FROM_UNIXTIME(pubTime,'%Y') = year(CURDATE())

收支纪录计算余额

db.png

status 1 收入
status 2 支出

select 
m.id,
m.money,
m.status,
m.time,
(
    select SUM(
            case when mm.`status` = 1 then mm.money 
            when mm.status = 2 then -mm.money end
            )
        from money mm WHERE m.time <= mm.time) sum

from money m order by m.time desc
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,508评论 6 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 《高性能MySQL》&《MySQL技术内幕 InnoDB存储引擎》笔记 第一章 MySQL架构与历史 MySQL的...
    xiaogmail阅读 12,583评论 0 39
  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,288评论 0 4
  • 我们对青春最大的误解,就是有人对你好,以为就叫爱情,明明只是路人,却当做挚爱,爱一个人,以为就可以一辈子,伤一次心...
    菠菜黄阅读 238评论 0 0