`
zzhonghe
  • 浏览: 244419 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

SQL经典模式 - 行转列

    博客分类:
  • DB
阅读更多
不知道读者有没有类似的遭遇,遇到下面这样的设计:

#雇员信息
create table employee (eId int, propName varchar(10), propName varchar(10));

insert into employee values (1, 'firstName','Calvin'),(1,'lastName','Zhou'),(1,'age','25'), (1,'gender','1')
insert into employee values (2, 'firstName','Grace'),(2,'lastName','Lai'),(2,'age','28'), (2,'gender','0')
insert into employee values (3, 'firstName','Morgan'),(3,'age','28');


#雇员考评
create table score (eId int, score int);

insert into score (1,85), (2,60), (3,90), (4,20);


#用一条SQL语句找出考评在 80分以上, 年龄在28岁以下,并且性别是男 的雇员所有信息

遇到这个需求的时候,开发人员一般都要在心里开始访问DBA的家人了,他妈怎么设计的表,干嘛不把employee的属性集中放一行,搞得都没法查

于是,一般的做法:
1.先找一遍score表,查出所有的 score>85的eId,
2.然后再去employee表把这些Id相关的信息都加到内存里面,比较属性名,拼成一个Employee对象,
3.最后再循环这个对象,对age,和gender属性进行过滤


这个过程麻烦的要死,但如果熟练掌握行转列的技巧,那么就是轻而易举一条语句就查出了所有复合要求的Employee对象


这个技巧就是 case when, 配合group by,以及聚合函数 max或者min 使用:

步骤一, case when, 将行拆到列上面来, 没有值的列用Null表示

select
eId,
case propName when 'firstName' then propValue else null end as firstName,
case propName when 'lastName' then propValue else null end as lastName,
case propName when 'age' then propValue else null end as age,
case propName when 'gender' then propValue else null end as gender
from employee;

步骤二:然后对表进行group by,每个eId一个组:

select
eId,
case propName when 'firstName' then propValue else null end as firstName,
case propName when 'lastName' then propValue else null end as lastName,
case propName when 'age' then propValue else null end as age,
case propName when 'gender' then propValue else null end as gender
from employee group by eId;

步骤三: 用max,过滤掉所有的null

select
eId,
max(case propName when 'firstName' then propValue else null end) as firstName,
max(case propName when 'lastName' then propValue else null end) as lastName,
max(case propName when 'age' then propValue else null end) as age,
max(case propName when 'gender' then propValue else null end) as gender
from employee group by eId;




有了上面这个employee的临时表,就好办了,在这个基础上,添加Score条件的过滤:


select
eId,
max(case propName when 'firstName' then propValue else null end) as firstName,
max(case propName when 'lastName' then propValue else null end) as lastName,
max(case propName when 'age' then propValue else null end) as age,
max(case propName when 'gender' then propValue else null end) as gender
from employee
where eId in (select eId from score where score>80)
group by eId;


最后再添加上employee本身条件28岁以下,男

select tmp.* from (..) as tmp where tmp.age<28 and tmp.gender=1




分享到:
评论

相关推荐

    SQL语句解释大全-从数据库表中检索数据行和列

    SQL语句解释大全--从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 --数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --...

    SQL语句大全-可当字典用

    SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 --数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --从数据库...

    学习SQL语句之SQL语句大全

     SELECT --从数据库表中检索数据行和列  INSERT --向数据库表添加新数据行  DELETE --从数据库表中删除数据行  UPDATE --更新数据库表中的数据  --数据定义  CREATE TABLE --创建一个数据库表  DROP TABLE --...

    精通SQL--结构化查询语言详解

    8.3.2 group by子句根据多列组合行 150 8.3.3 rollup运算符和cube运算符 151 8.3.4 group by子句中的null值处理 153 8.3.5 having子句 153 8.3.6 having子句与where子句 154 8.3.7 select语句各查询子句总结 ...

    SQL语句全集及操作大全

    SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 -数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --从数据库中删除...

    Transact-SQL语句总结大全

    SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 --数据定义 CREATE TABLE --创建一个数据库表 DROP ...

    经典SQL语句大全

    EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。 C: INTERSECT 运算符 INTERSECT 运算符通过只包括 ...

    常用SQL语句大全

    语 句 功 能 --数据操作 SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 --数据定义 CREATE TABLE --创建一个数据库...

    SQL 基本命令大全

    SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 --数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --从数据库...

    SQL语句大全大全(经典珍藏版)

    SQL语句大全大全(经典珍藏版) --数据操作 SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 -数据定义 CREATE TABLE...

    SQL语法速成手册.pdf

    主键(primary key)- 一列(或一组列),其值能够唯一标识表中每一行。 SQL语法 SQL(Structured Query Language),标准 SQL 由 ANSI 标准委员会管理,从而 称为ANSI SQL-各个 DBMS都有自己的实现,如PL/SQL、...

    sql经典语句一部分

    经典SQL语句大全 一、基础 1、说明:创建数据库 CREATE DATABASE database-name 2、说明:删除数据库 drop database dbname 3、说明:备份sql server --- 创建 备份数据的 device USE master EXEC sp_addumpdevice ...

    net实例常用SQL语句大全

     SELECT --从数据库表中检索数据行和列  INSERT --向数据库表添加新数据行  DELETE --从数据库表中删除数据行  UPDATE --更新数据库表中的数据 --数据定义  CREATE TABLE --创建一个数据库表  DROP TABLE --从...

    MS SQL入门-进阶-实战培训.pdf

    1.3 SQL 管理工具介绍   1.3.1 SQL server配置管理器   1.3.2 SQL server网络配置   1.3.3 连接SQL server服务器   1.3.4 服务器属性配置   1.3.5 命令行下的SQL管理工具   2 设计与管理数据库和对象  ...

    MySQL中将一列以逗号分隔的值行转列的实现

    有时会遇到没有遵守第一范式设计模式的业务表。即一列中存储了多个属性值。如下表 pk value 1 ET,AT 2 AT,BT 3 AT,DT 4 DT,CT,AT 一般有这两种常见需求(测试数据见文末) 1.得到所有的不重复的值,...

    SQL COOKBOOK(压缩1/2)

    1.1从表中检索所有行和列 1.2从表中检索部分行 1.3查找满足多个条件的行 1.4从表中检索部分列 1.5为列取有意义的名称 1.6在WHERE子句中引用取别名的列 1.7连接列值 1.8在SELECT语句中使用条件逻辑 1.9限制...

    SQL语句大全

    SELECT --从数据库表中检索数据行和列 INSERT -- 向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 -数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --从...

    SQL语法大全

    SQL语法大全 SQL语法大全 1. ASP与Access数据库连接: dim conn,mdbfile mdbfile=server.mappath("数据库名称.mdb") set conn=server.createobject("adodb.connection") conn.open "driver={microsoft access ...

    SQL语句大全大全(官方修正典藏版)

    SELECT --从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 -数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --从...

Global site tag (gtag.js) - Google Analytics