zoukankan      html  css  js  c++  java
  • sql server和oracle行转列的一种典型方法

    前言:网上有不少文章是讲行转列的,但是大部分都是直接贴代码,忽视了中间过程,本人自己思考了下为什么要这样实现,并且做了如下的笔记,对有些懂的人来说可能没有价值,希望对还不懂的人有一点借鉴意义。

    对于有些业务来说,数据在表中的存储和其最终的Grid表现恰好相当于把源表倒转,那么这个时候我们就碰到了如何把行转化为列的问题,为了简化问题,我们且看如下查询出来的数据,您不必关心表的设计以及sql语句:

    image

    假设用到的sql语句为:

    SELECT [姓名],[时代],[金钱]
      
    FROM [test].[dbo].[people]  

    这个表存储了两个人在不同时代(时代是固定的三个:年轻、中年和老年)拥有的金币,其中:

    张三在年轻、中年和老年时期分别拥有1000、5000、800个金币;

    李四在年轻、中年和老年时期分别拥有1200、6000、500个金币。

    现在我们想把两人在不同阶段拥有的金币用类似如下的表格来展现:

    姓名 年轻 中年 老年
    张三 1000 5000 800
    李四 1200 6000 500

    我们现在考虑用最简单和直接的办法来实现,其实关键是如何创建那些需要增加的列,且如何设定其值,现在我们来创建“年轻”列,关键的问题是,这一列的值如何设定?合法的逻辑应该是这样:如果该行不是“年轻”时代,那么其“金钱”我们认为是0,那么sql语句如何写呢?

    如果是用的sql server,那么肯定要用到case了:

    case  [时代] when '年轻' then [金钱] else 0 end as 年轻



    case when  [时代]= '年轻' then [金钱] else 0 end as 年轻

    如果用的是oracle,那么要用到decode函数,decode(1+1,3,'错',2,'是',5,'错','都不满足下返回的值'),这个函数将返回“是”,具体用法限于篇幅这里不再介绍,相信大家从这个式子可以大概了解到其意思,用decode创建“年轻”列的句子是:完整的sql语句如下所示:

    decode(时代,'年轻',金钱,0)) 年轻

    SELECT [姓名],[时代],[金钱]

    case  [时代] when '年轻' then [金钱] else 0 end as 年轻,
    case  [时代] when '中年' then [金钱] else 0 end as 中年,
    case  [时代] when '老年' then [金钱] else 0 end as 老年 

      
    FROM [test].[dbo].[people] 

    现在我们来看看其执行结果:

    image

    相信看到这个结果,大家都知道下一步该做什么,那就是分组:按姓名分组,并且对三个时代的金钱进行求和:

    select [姓名],sum([年轻]as 年轻,sum([中年]as 中年,sum([老年]as 老年 from
    (
    SELECT [姓名],[时代],[金钱]

    case  [时代] when '年轻' then [金钱] else 0 end as 年轻,
    case  [时代] when '中年' then [金钱] else 0 end as 中年,
    case  [时代] when '老年' then [金钱] else 0 end as 老年 

      
    FROM [test].[dbo].[people]) t
      
    group by [姓名]


    这里用到了子查询,是为了逻辑更清晰一点,其实可以不用子查询;至于oracle下的sql语句,除了要使用decode之外,其余几乎一致,本人正是在oracle中实现之后才研究了下sql server下的实现方式。

    最后看看结果:

    image

    事实上,当列不固定的时候,比如除了“年轻”、“中年”、“老年”以外还有其他的未知的时代,实现思路其实基本一致,只是需要动态生成sql而已。

  • 相关阅读:
    java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header.
    spring-session-data-redis依赖冲突问题
    centos7启动iptables时报Job for iptables.service failed because the control process exited with error cod
    图片上传后台服务报内存溢出 Out Of Memory Java heap space
    mysql 数据库密码忘记重置 进行远程连接
    打Jar包
    Type interface com.innovationV2.mapper.UserMapper is not known to the MapperRegistry
    关于java基础类型Integer String的clone()
    clion使用clang编译
    token & refresh token 机制总结
  • 原文地址:https://www.cnblogs.com/hxwzwiy/p/2418623.html
Copyright © 2011-2022 走看看