zoukankan      html  css  js  c++  java
  • SQL查询中行转列的问题

    这周在工作中遇到一个SQL查询行转列的问题,在网上搜了下,找到了一些案例,自己试着写了下,希望对朋友们有所帮助!

    目录结构如下:

    • 行转列
    • 列转行

    [一]、行转列

    1.1、初始测试数据

    表结构:TEST_TB_GRADE

    Sql代码  收藏代码
    1. create table TEST_TB_GRADE  
    2. (  
    3.   ID        NUMBER(10) not null,  
    4.   USER_NAME VARCHAR2(20 CHAR),  
    5.   COURSE    VARCHAR2(20 CHAR),  
    6.   SCORE     FLOAT  
    7. )  

     初始数据如下图:


                            

    1.2、 如果需要实现如下的查询效果图:


                         

    这就是最常见的行转列,主要原理是利用decode函数、聚集函数(sum),结合group by分组实现的,具体的sql如下:

    Sql代码  收藏代码
    1. select t.user_name,  
    2.   sum(decode(t.course, '语文', score,null)) as CHINESE,  
    3.   sum(decode(t.course, '数学', score,null)) as MATH,  
    4.   sum(decode(t.course, '英语', score,null)) as ENGLISH  
    5. from test_tb_grade t  
    6. group by t.user_name  
    7. order by t.user_name  

     

    1.3、延伸

    如果要实现对各门功课的不同分数段进行统计,效果图如下:


                     

    具体的实现sql如下:

    Sql代码  收藏代码
    1. select t2.SCORE_GP,  
    2.   sum(decode(t2.course, '语文', COUNTNUM,null)) as CHINESE,  
    3.   sum(decode(t2.course, '数学', COUNTNUM,null)) as MATH,  
    4.   sum(decode(t2.course, '英语', COUNTNUM,null)) as ENGLISH  
    5. from (  
    6.   select t.course,  
    7.          case when t.score  <60 then '00-60'  
    8.               when t.score >=60 and t.score <80  then '60-80'  
    9.               when t.score >=80 then '80-100' end as SCORE_GP,  
    10.          count(t.score) as COUNTNUM  
    11.   FROM test_tb_grade t  
    12.   group by t.course,   
    13.         case when t.score  <60  then '00-60'  
    14.               when t.score >=60 and t.score <80  then '60-80'  
    15.               when t.score >=80 then '80-100' end  
    16.   order by t.course ) t2  
    17. group by t2.SCORE_GP  
    18. order by t2.SCORE_GP  

     

    [二]、列转行

    1.1、初始测试数据

            表结构:TEST_TB_GRADE2

    Sql代码  收藏代码
    1. create table TEST_TB_GRADE2  
    2. (  
    3.   ID         NUMBER(10) not null,  
    4.   USER_NAME  VARCHAR2(20 CHAR),  
    5.   CN_SCORE   FLOAT,  
    6.   MATH_SCORE FLOAT,  
    7.   EN_SCORE   FLOAT  
    8. )  

     

            初始数据如下图:


            

    1.2、 如果需要实现如下的查询效果图:


                           

    这就是最常见的列转行,主要原理是利用SQL里面的union,具体的sql语句如下:

    Sql代码  收藏代码
    1. select user_name, '语文' COURSE , CN_SCORE as SCORE from test_tb_grade2   
    2. union select user_name, '数学' COURSE, MATH_SCORE as SCORE from test_tb_grade2   
    3. union select user_name, '英语' COURSE, EN_SCORE as SCORE from test_tb_grade2   
    4. order by user_name,COURSE   

     也可以利用【 insert all into ... select 】来实现,首先需要先建一个表TEST_TB_GRADE3:

    Sql代码  收藏代码
    1. create table TEST_TB_GRADE3    
    2.     (   
    3.       USER_NAME VARCHAR2(20 CHAR),    
    4.       COURSE    VARCHAR2(20 CHAR),    
    5.       SCORE     FLOAT    
    6.     )    

     再执行下面的sql:

    Sql代码  收藏代码
    1. insert all  
    2. into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, '语文', CN_SCORE)  
    3. into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, '数学', MATH_SCORE)  
    4. into test_tb_grade3(USER_NAME,COURSE,SCORE) values(user_name, '英语', EN_SCORE)  
    5. select user_name, CN_SCORE, MATH_SCORE, EN_SCORE from test_tb_grade2;  
    6. commit;  

     别忘记commit操作,然后再查询TEST_TB_GRADE3,发现表中的数据就是列转成行了。

    本文连接:http://sjsky.iteye.com/blog/1152167

    以上转载自网上的一篇博客,本人对decode()函数也不是很了解,于是又去百度了下decode()函数

     decode()函数简介:

    主要作用:将查询结果翻译成其他值(即以其他形式表现出来,以下举例说明);

    使用方法:

    Select decode(columnname,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)

    From talbename

    Where …

    其中columnname为要选择的table中所定义的column,

    ·含义解释:

    decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)的理解如下:

    if (条件==值1)

     then    

    return(翻译值1)

    elsif (条件==值2)

    then    

    return(翻译值2)    

    ......

    elsif (条件==值n)

     then    

    return(翻译值n)

    else    

    return(缺省值)

    end if

    注:其中缺省值可以是你要选择的column name 本身,也可以是你想定义的其他值,比如Other等;

    举例说明:

    现定义一table名为output,其中定义两个column分别为monthid(var型)和sale(number型),若sale值=1000时翻译为D,=2000时翻译为C,=3000时翻译为B,=4000时翻译为A,如是其他值则翻译为Other;

    SQL如下:

    Select monthid , decode (sale,1000,'D',2000,'C',3000,'B',4000,'A',’Other’) sale from output

    特殊情况:

    若只与一个值进行比较

    Select monthid ,decode(sale, NULL,‘---’,sale) sale from output

    另:decode中可使用其他函数,如nvl函数或sign()函数等;

    NVL(EXPR1,EXPR2)

    若EXPR1是NULL,则返回EXPR2,否则返回EXPR1.

    SELECT NAME,NVL(TO_CHAR(COMM),'NOT APPLICATION') FROM TABLE1;

    如果用到decode函数中就是

    select monthid,decode(nvl(sale,6000),6000,'NG','OK') from output

    sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1,

    如果取较小值就是

    select monthid,decode(sign(sale-6000),-1,sale,6000) from output,即达到取较小值的目的。

    自己解释下 decode(条件,值1,翻译值1,值2,翻译值2,值3,翻译值3,值4,翻译值4....)
    其中条件可以是表中的一列 例如 学生表中的课程这列,另外decode()函数是oracle专有的,而我用的是sql server2012

    本文中的例子是这样的

    USE [ RUNOOB ]
    create table TEST_TB_GRADE
    (
    ID INT IDENTITY(1,1) PRIMARY KEY ,
    USER_NAME VARCHAR(20),
    COURSE varchar(20),
    SCORE FLOAT
    )

    USE [ RUNOOB ]
    SELECT * FROM dbo.TEST_TB_GRADE ORDER BY USER_NAME --按照用户名排序

     测试数据如下

     

  • 相关阅读:
    内存泄漏 Memory Leaks 内存优化 MD
    Handler Thread 内部类引起内存泄露分析
    为什么不取消注册BroadcastReceiver会导致内存泄漏
    WebChromeClient 简介 API 案例
    WebViewClient 简介 API 案例
    java.net.URI 简介 文档 API
    android.net.Uri 简介 API
    RV 多样式 MultiType 聊天界面 消息类型 MD
    JS函数声明与定义,作用域,函数声明与表达式的区别
    CSS中table tr:nth-child(even)改变tr背景颜色: IE7,8无效
  • 原文地址:https://www.cnblogs.com/kelly1314/p/7092760.html
Copyright © 2011-2022 走看看