Oracle 行转列 动态出转换的列

2023-11-06

10月的第二天,前天写了个Oracle中行转列的pivot的基本使用方法,然后,因为pivot的用法中,正常情况下,我们需要转出多少个列,都得在我们的sql中完完整整地写出,而不能直接在里面写个查询来动态转换。然后,趁着祖国母亲的生日,这几天放假,整理一下处理方法。

一、运行环境

Win10,Oracle Database 11g r2,plsql 12。

二、效果预览

1、固定转换列的方法

2、存储过程处理

1)调用存储过程

2)查指定的视图即可

3、两种方法的关系

其实原理很简单,就是通过动态sql,去把你不愿意写,或者说是不确定的转换列数,通过查询查出来,拼接进去,然后执行拼接后的sql,创建视图。

三、存储过程

create or replace procedure p_RowsToCols(as_sql       in varchar2 --源数据的查询sql
                                        ,as_sql_cols  in varchar2 --动态转换列的查询sql,要求转为列的那列,字段名必须为cols,支持排序
                                        ,as_aggCol    in varchar2 --对应pivot函数的 聚合函数
                                        ,as_changeCol in varchar2 --源数据中,要转为列的字段名
                                        ,as_viewName  in varchar2 --结果输出的视图名,执行完后查此视图即可
                                         ) is
  ls_sql varchar2(4000);
  ls_in  varchar2(4000);
begin
  --拼接in的内容
  ls_sql := 'select listagg(''''''''||cols||'''''' "''||cols||''"'', '','')within group(order by rn) ' || 
              'from (select rownum rn, cols from (' || as_sql_cols || '))';
  execute immediate ls_sql
    into ls_in;
 
  --创建视图
  ls_sql := 'create or replace view ' || as_viewName ||' as ' ||
            'select * from (' || as_sql || ') ' ||
             'pivot (' || as_aggCol || ' for ' || as_changeCol || ' in (' || ls_in || '))';
  execute immediate ls_sql;
end p_RowsToCols;

四、测试数据及SQL

贴一下我测试的数据和代码。

--建表
--drop table SalesList;
create table SalesList(
    keHu                varchar2(20),   --客户
    shangPinId          number(8),      --商品Id
    shangPin            varchar2(20),   --商品名称
    salesNum            number(8)       --销售数量
);
 
--插入数据
declare
  --谈几个客户
  cursor lr_kh is 
  select regexp_substr('张三、李四、王五、赵六','[^、]+',1, level) keHu from dual
   connect by level <= 4;
  --进点货
  cursor lr_sp is 
  select level shangPinId, regexp_substr('上衣、裤子、袜子、帽子','[^、]+',1, level) shangPin from dual
   connect by level <= 4;
begin
  --循环插入
  for v_kh in lr_kh loop
     for v_sp in lr_sp loop
        insert into SalesList
        select v_kh.keHu, v_sp.shangPinId, v_sp.shangPin, floor(dbms_random.value(10,50)) from dual;
     end loop;
  end loop;
  commit;
end;
/
 
--看下源数据
select * from salesList a;
 
--固定行转列
select *
  from (select kehu, shangPin, salesNum from salesList) pivot(
    max(salesNum) for shangPin in (
        '上衣' as 上衣,
        '裤子' as 裤子,
        '袜子' as 袜子,
        '帽子' as 帽子
    )
  );
 
--动态行转列
call p_RowsToCols('select keHu, shangPin, salesNum from salesList',
                  'select distinct shangPinId, shangPin cols from salesList order by shangPinId',
                  'max(salesNum)',
                  'shangPin',
                  'sales_RowsToCols');
 
select * from sales_RowsToCols;

​​​​​​

完结!!!!!!!!!!!!!!!!!!!!!!

结尾来个悲伤的彩蛋,闻者伤心,听者落泪!

上面介绍的方法是一个很简单的思路,然鹅!!!在找到这个思路之前,我还傻傻的做了另外一个版本,一个比较复杂的版本。。。花了有差不多半天时间。我按照这个思路,刚做完的时候有多开心,现在的我,就有多伤心!!不过不忍心直接del掉,还是在这边记录一下吧,思路大概是这个样几:

同样是存储过程,传入数据源的查询sql,通过存储过程处理,拼接成完整的pivot函数需要的sql,然后直接执行,查出结果,insert到一张通用的记录表中,然后建一个视图,指向这部分数据。

完结篇.1 效果预览

测试数据参考上面的插入sql,同样的数据。

1、第一个参数:必填,数据源的查询,列数不限,但查询的倒数第二列为转换列,最后一列数据列;

2、第二个参数:

     1)可为空,内容为要转换出的列的查询sql,可指定表头顺序及显示的表头名称。为空时即从数据源查询的倒数第二列中取distinct值,并不保证排序。

     2)查询结果必须为三列,第一列为数字排序列(不需要的话这列就随便指定一个数字就行),第二列对应数据源中转换列的值,第三列即为对应的表头转换后的名称(如果名称不需要改变,这列跟第二列保持一样就行)。

3、第三个参数:可为空,内容就是处理完后要查的视图名。为空的话,即默认为tmp_rowToCol。

完结篇.2 跟pivot的对应关系

完结篇.3 其他好玩的东西

1、因为我们这个方法的话是吧查出的内容存到表里,然后通过视图直接指向数据的,刚才指定的视图Sale_RowToCol,具体创建语法,就是下面这个,tmp_RowToCol_XiaoXianNv为数据存储的表,fbs = '1' 表示是转换的实际数据,fguid是本次转换的一个key。

 

我们查下这个表中实际的数据,这是一个在首次调用存储过程的时候会创建的一个表,203个字段,不超过这么多列的都可以通过我们的存储过程去转并存储数据。

然后,这个表的数据是会一直保存着的,emm...好像没啥卵用,不过说不定哪天脑子抽了向往前查查这个还是挺有意思的。。。(说得我自己都不信)

完结篇.4 贴代码

csdn的高亮。。好像不太友好

/**
 * 动态进行行列转换,结果集可在一个可指定的视图中查询(默认为tmp_rowToCol)
 * 适用于把一列的值转成多列,转换效果与Oracle的pivot相同,但不需要写死转换出来的每一个列
 * 转换后的数据所存的实体表为tmp_RowToCol_XiaoXianNv,通过一个guid关联到指定的视图
 * tmp_RowToCol_XiaoXianNv表在此过程中不做删除操作。所以如果永久了怕是数据也会挺多。
 * 如果不需要保留数据的话,可以考虑把这个表建为一个会话级临时表,然后转换结果插入后不提交。
 * 这样在同一会话下可查询,提交或者回滚后数据就不复存在。
 * 
 * 转换思路:
 *     1、通过动态sql,拼接出 for XXX in () 里面那部分内容,然后通过动态sql执行并把结果插入一个表中
 *     2、获取固定列、转出列的列名,进行拼接,然后创建视图指向上一步插入的数据
 * 
 * author: lhy
 * date: 2018-10-01 祖国万岁
 * 
 * as_sql             要转换的数据源查询
 *                    对查询结果集的要求:至少3列,
 *                        最后一列为数据值
 *                        倒数第二列为要转成列的内容
 *                        前面的就是不需转换的列
 * as_sql_col         查询要转的列名,如果不指定,即从as_sql的查询的倒数第二列中获取distinct值
 *                    对查询的结果集要求:必须为三列
 *                        对应pivot函数中的:for xxx in('值1' as colNm1,'值2' as colNm2 ...)
 *                        第一列:排序列,要求为数字
 *                        第二列:值(值1..值2)
 *                        第三列:字段名(colNm1..colNm2)
 *                        当然,你不care最后结果的字段的排序和字段名的话,第一列您直接指定一个固定值就行,第三列跟第二列一样也行
 * as_tableName       指定一个视图名来存放转换后的数据,调用存储过程后,通过此视图查询结果集
 */
create or replace procedure p_rowToCol(as_sql in varchar2, as_sql_col in varchar2, as_viewName in varchar2) is
   lr_curid          integer;            --游标id
   ls_cnt            number(8);          --计数用
   ls_sql            varchar2(4000);     --sql语句
   ls_sql_col        varchar2(4000);     --同 as_sql_col
   ls_rsltTab        dbms_sql.desc_tab;  --存放返回的结果集
   ls_viewName       varchar2(200);      --转换结果存放的表名
   ls_guid           varchar2(50);       --当次转换的guid
   ls_aggColNm       varchar2(50);       --对应pivot的聚合列的列名
   ls_changeColNm    varchar2(50);       --转换列的列名
   ls_cnt_col        number(8);          --要转换出来的列数
   ls_in_text        varchar2(4000);     --对应for()的内容
   ls_cnt_end        number(8);          --最终查询结果的列数
   ls_sql_end        varchar2(4000);     --最终的插入语句
   ls_col_add        varchar2(4000);     --存放转出的列名
   ls_col_fixed      varchar2(4000);     --存放不需要转换的列名
   ls_col_insert     varchar2(4000);     --存放插入的字段
   ls_col_view       varchar2(4000);     --视图的字段
   ls_sql_view       varchar2(4000);     --存放最后的视图的sql
   ls_thead          varchar2(4000);     --拼接一个表头出来,说不定可以回查
 
begin
  --两步准备工作,其实如果做过一次,后面的代码中其实都不需要执行这两步了
 
   --准备工作1、看下是否存在tmp_RowToCol_XiaoXianNv这个表,首次使用不存在的话建一个(用于存放转换后的数据)
   select count(*) into ls_cnt from all_tables where table_name = upper('tmp_RowToCol_XiaoXianNv');
   if ls_cnt = 0 then
      ls_sql := 'create table tmp_RowToCol_XiaoXianNv(fguid varchar2(50),fopdt date default sysdate,fbs varchar2(8),';
      for i in 1..200 loop
         if i = 200 then
            ls_sql := ls_sql || 'C' || i || ' varchar2(4000))';
         else
            ls_sql := ls_sql || 'C' || i || ' varchar2(4000),';
         end if;
      end loop;
      execute immediate ls_sql;
      --怕以后数据多查询慢的话还可以建个索引给fguid字段
      execute immediate 'create index IDX_ROWSTOCOLS_FGUID on tmp_RowToCol_XiaoXianNv (fguid)';
   end if;
   --准备工作2、看下是否存在一个tmp_XiaoXianNv_t1这个临时表,首次使用不存在的话建一个(用于处理转换列排序)
   select count(*) into ls_cnt from all_tables where table_name = upper('tmp_XiaoXianNv_t1');
   if ls_cnt = 0 then
      ls_sql := 'create global temporary table tmp_XiaoXianNv_t1(fseq NUMBER(20),c1 VARCHAR2(4000),c2 VARCHAR2(4000)) on commit delete rows';
      execute immediate ls_sql;
   end if;
   --取个guid,准备开干
   --这个就是这一次转换的的key,以后要找这次转换的数据都可以拿着这个key到tmp_RowToCol_XiaoXianNv找
   --所以其实也可以通过传参来手动指定这个key,然后以后想查回来这次的数据都会比较方便
   ls_guid := sys_guid();
   --获取转换列和聚合列的列名,即as_sql查询结果的倒数两列
   ls_sql     := as_sql;
   lr_curid   := dbms_sql.open_cursor;
   dbms_sql.parse(lr_curid, ls_sql, dbms_sql.native);
   dbms_sql.describe_columns(lr_curid, ls_cnt, ls_rsltTab);
   ls_changeColNm := ls_rsltTab(ls_cnt - 1).col_name;      --倒数第2列,获取转换列列名
   ls_aggColNm    := ls_rsltTab(ls_cnt).col_name;          --倒数第1列,获取聚合列列名
   ls_cnt         := ls_cnt - 2;                           --不需要转换的列数
   --拼接不需要转换的列名,用于后面建视图(part 1)
   for i in 1..ls_cnt loop
      ls_col_fixed := ls_col_fixed || ls_rsltTab(i).col_name || ', ';
   end loop;
   dbms_sql.close_cursor(lr_curid);
   --拼接 for xxx in ('值1' as colNm1,'值2' as colNm2 ...) 部分
   --获取所有列名并拼接
   --1、先把所有列名的查询sql搞定
   if as_sql_col is null then
      ls_sql_col := 'select rownum rn, c1, c1 c2 from (select distinct '|| ls_changeColNm || ' c1 from (' || as_sql || ') order by ' || ls_changeColNm || ')';
   else
      ls_sql_col := as_sql_col;
   end if;
   --2、把转换列的数据插入到临时表
   execute immediate 'delete from tmp_XiaoXianNv_t1';
   ls_sql        := 'insert into tmp_XiaoXianNv_t1 (fseq, c1, c2) '|| ls_sql_col;
   execute immediate ls_sql;
   --3、ls_cnt_col count出要转换出的列数
   execute immediate 'select count(*) from tmp_XiaoXianNv_t1' into ls_cnt_col;
   --顺便算一下最终查询结果的列数
   ls_cnt_end := ls_cnt + ls_cnt_col;
   --4、拼接for xx in () 里面的内容
   ls_sql := 'select listagg(''''''''||c1||'''''' ''||c2 , '', '') within group(order by fseq ) from tmp_XiaoXianNv_t1 a';
   execute immediate ls_sql into ls_in_text;
   --5、顺便拼接出行转列转换出来的字段名,用于后面建视图(part 2)
   ls_sql := 'select listagg(c2,'','')within group(order by fseq) from tmp_XiaoXianNv_t1';
   execute immediate ls_sql into ls_col_add;
   --拼接插入的表的字段 tmp_RowToCol_XiaoXianNv(c1,c2,c3...)
   select listagg(col, ', ') within group(order by rn)
     into ls_col_insert
     from (select rownum rn, 'c' || rownum col
             from dual
     connect by rownum <= ls_cnt_end);
   --拼接pivot的insert sql,插入内容,fbs为标识字段,标记为1,即为正式数据
   ls_sql_end      := 'insert into tmp_RowToCol_XiaoXianNv (fguid,fbs,' || ls_col_insert || ') '
                      ||'select '''|| ls_guid ||''' fguid,''1'',t.* from ('
                      || as_sql || ') PIVOT(max(' || ls_aggColNm || ') for ' || ls_changeColNm || ' in ('
                      || ls_in_text || ')) t' ;
   execute immediate ls_sql_end;
   commit;
   
   --拼接表头的字段
   ls_thead        := ls_col_fixed || ls_col_add;
   ls_thead        := replace(ls_thead,' ');
   ls_col_view     := ls_thead;     --转存一下给下面拼接视图的使用
   
   select listagg(''''||col||'''',',')within group(order by rn) 
     into ls_thead from (
          select level rn, regexp_substr(ls_thead,'[^,]+',1,level) col 
            from dual connect by level <= ls_cnt_end
     );
   --拼接pivot的insert sql,插入内容,fbs为标识字段,标记为转换后的字段数,即ls_cnt_end变量,即为正式数据
   ls_sql          := 'insert into tmp_RowToCol_XiaoXianNv (fguid,fbs,' || ls_col_insert || ') values('''|| ls_guid ||''','''||ls_cnt_end||''','||ls_thead||')';
   execute immediate ls_sql;
   commit;
   --拿到结果视图名,默认为tmp_rowToCol
   if as_viewName is null then
      ls_viewName := 'tmp_rowToCol';
   else
      ls_viewName := as_viewName;
   end if;
   /***************************************这部分的代码可以直接删掉************************************
   --上面是根据前面的数据拼接出来的视图的字段ls_col_view,如果我们是只知道一个guid的时候,我们其实也可以去从数据表中查出表头,然后拼接
   ls_sql         := 'select max(fbs) from tmp_RowToCol_XiaoXianNv where fguid = '''||ls_guid||''' and fbs <> ''1''';
   execute immediate ls_sql into ls_cnt_end;  --获取列数
   
   select listagg(col,'||'',''||')within group(order by rn) 
     into ls_sql from (
          select level rn, 'C'||level col from dual connect by level <= ls_cnt_end
     );
   
   ls_sql         := 'select '|| ls_sql || ' from tmp_RowToCol_XiaoXianNv where fguid = '''||ls_guid||''' and fbs <> ''1''';
   execute immediate ls_sql into ls_col_view; --获取视图列名ls_col_view,这里得到的跟上面获取到的是一样的
   **********************************************************************************************/
   --拼接视图的字段别名转换关系  c1 字段1, c2 字段2 ...
   select listagg(c1||' '||col,',')within group(order by rn) 
     into ls_col_view from (
          select 'C'||level c1, level rn, regexp_substr(ls_col_view,'[^,]+',1,level) col 
            from dual connect by level <= ls_cnt_end
     );
   --视图呈现
   ls_sql_view     := 'create or replace view '|| ls_viewName ||' as select '|| ls_col_view || ' from tmp_RowToCol_XiaoXianNv where fbs = ''1'' and fguid = '''|| ls_guid || '''';
   execute immediate ls_sql_view;
end p_rowToCol;

完结篇.5 测试SQL

 
--建表
--drop table SalesList;
create table SalesList(
    keHu                varchar2(20),   --客户
    shangPinId          number(8),      --商品Id
    shangPin            varchar2(20),   --商品名称
    salesNum            number(8)       --销售数量
);
 
--插入数据
declare
  --谈几个客户
  cursor lr_kh is 
  select regexp_substr('张三、李四、王五、赵六','[^、]+',1, level) keHu from dual
   connect by level <= 4;
  --进点货
  cursor lr_sp is 
  select level shangPinId, regexp_substr('上衣、裤子、袜子、帽子','[^、]+',1, level) shangPin from dual
   connect by level <= 4;
begin
  --循环插入
  for v_kh in lr_kh loop
     for v_sp in lr_sp loop
        insert into SalesList
        select v_kh.keHu, v_sp.shangPinId, v_sp.shangPin, floor(dbms_random.value(10,50)) from dual;
     end loop;
  end loop;
  commit;
end;
/
 
--查看下数据
select * from salesList a; 
 
--固定行转列
select *
  from (select kehu, shangPin, salesNum from salesList) pivot(
    max(salesNum) for shangPin in (
        '上衣' as 上衣数量,
        '裤子' as 裤子数量,
        '袜子' as 袜子数量,
        '帽子' as 帽子数量
    )
  );
 
--动态行转列
call p_rowtocol('select keHu, shangPin, salesNum from SalesList',
                '',
                'Sale_RowToCol');
 
select * from Sale_RowToCol; 
 
--完整版
call p_rowtocol('select keHu 客户, shangPin, salesNum from SalesList',
                'select distinct shangPinId, shangPin, shangPin||''数量'' from salesList order by shangPinId',
                'Sale_RowToCol');
 
select * from Sale_RowToCol;
 
--数据存储的表
select * from tmp_RowToCol_XiaoXianNv
  1.  

结束语?没有

啊对,这个存储过程中有建表和建视图的语法,如果你的用户没有权限的话需要用dba用户给一下权限:

grant create table to user;

grant create view to user;

================2019年4月25日 更新================

评论区一个小伙伴报的bug。

拼接出来的sql语句,pivot(xxx for xxx in ('0' 0, '1' 1, '2' 2)) 的这部分,当列为纯数字的时候,别名要加个双引号。

就是说,拼接出来的应该是 pivot(xxx for xxx in ('0' "0", '1' "1", '2' "2")) 才对。

修改内容:代码的11行,拼接列别名的时候,添加个双引号把列名包住

更新后代码如下:

嗯,再次感谢提bug的小伙伴。
————————————————
https://blog.csdn.net/Huay_Li/article/details/82924443

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle 行转列 动态出转换的列 的相关文章

随机推荐

  • C++——初始化列表

    初始化列表 在构造函数执行时 先执行初始化列表 实现变量的初始化 然后再执行函数内部的语句 构造函数体赋值 在创建对象时 编译器通过调用构造函数 给对象中各个成员变量一个合适的初始值 class Date public Date int y
  • css中nth-child的属性

    参数为整数 nth child 1 它表示要选择父元素中索引为该数值的子元素 此时的索引值从1开始 参数是奇数偶数 nth child odd odd表示选择奇数项的子元素 nth child even even表示选择偶数项的子元素 参数
  • Tkinter 组件详解(一):Label

    Tkinter 组件详解之Label Label 标签 组件用于在屏幕上显示文本或图像 Label 组件仅能显示单一字体的文本 但文本可以跨越多行 另外 还可以为其中的个别字符加上下划线 例如用于表示键盘快捷键 何时使用 Label 组件
  • Linux驱动之input输入子系统

    目录 前言 介绍 input dev结构体 输入子系统的使用流程 实例测试 前言 输入子系统用于实现Linux系统输入设备 鼠标 键盘 触摸屏 游戏杆 驱动的一种框架 Linux内核将其中的固定部分放入内核 驱动开发时只需要实现其中的不固定
  • Web自动化测试从基础到项目实战之一启动不同的浏览器及配置

    在web自动化中目前selenium作为底层的自动化测试是目前运用最广的 但是各个公司都会在这个基础之上进行修改 首先当我们测试环境有了之后我们需要做得就是去配置我们的driver 这里的driver你可以理解为就是我们脚本和浏览器之间的桥
  • inuxCentos7.5安装jdk1.8(勿继续踩坑)

    LinuxCentos7 5安装jdk1 8 场景 错误出现 下面到了安装步骤 场景 首先我是一名后端 其实这种工作并不应该由我来干 先甩一下锅哈哈 由于我们公司没有真正的运维 所以什么事都需要我们后端来亲力亲为 一次偶然的机遇就把我派到了
  • Vue 代码检测(ESLint)

    每个人编码的习惯不一样 或美观或不美观 或者在编码的过程中会有些疏漏未曾发现 为提高代码美观度 提高代码审阅效率 使得多人协作时代码风格统一 规定一套编码规则并在编写的过程中遵守该规则变得很有必要 在一些比较正式的大公司 公司也会有一套自己
  • SSR是什么?Vue中怎么实现?

    一 是什么 Server Side Rendering 称其为SSR 意为服务端渲染 指由服务侧完成页面的 HTML 结构拼接的页面处理技术 发送到浏览器 然后为其绑定状态与事件 成为完全可交互页面的过程 先来看看Web3个阶段的发展史 传
  • SpringBoot--将微服务注册到Eureka Server上

    这节课我们一起来学习一下如何将微服务注册到Eureka Server上 关于如何操作Eureka 我们可以参考spring cloud的官方文档 我们先访问spring cloud的官网主页 如下图所示 目前官网Spring Cloud的最
  • pycharm专业版安装方法

    1 去官网下载安装包 有专业版 有社区版 专业版需要破解 社区版不要破解 2 打开pycharm应用程序安装64 bit 需要等待几秒 3 记住安装包解压位置 打开jetbrains 找到bin文件夹 D Program Files Jet
  • Java数据结构之优先级队列(堆)

    文章目录 一 优先级队列 一 概念 二 优先级队列的模拟实现 一 堆的概念 二 堆的存储结构 三 堆的创建 1 堆的创建和向下调整 2 堆的创建和向上调整 四 堆的插入和删除 1 堆的插入 堆的创建和向上调整 续 2 堆的删除 五 用堆模拟
  • Cadence 背景颜色设置

    目录 概述 一 Allegro PCB Designer 二 OrCAD Capture 三 总结 概述 有位粉丝问我 关于背景颜色设置问题 这里我写一篇文章吧 尽自己微薄之力帮助更多的人 加油 一 Allegro PCB Designer
  • 2.22笔记:linux命令不同颜色命令

    浅蓝色 表示软链接 灰色 表示其他文件 绿色 表示可执行文件 红色 表示压缩文件 蓝色 表示目录 红色闪烁 表示链接的文件有问题了 黄色 表示设备文件 包括block char fifo 管道文件 粉色 网络文件
  • bochs+gdb联调linux-0.11内核

    终于把bochs和gdb连起来了 下面描述下步骤以作记录 1 安装bochs 前面有篇文章介绍了bochs源码编译安装过程 这里安装也非常相似 只是命令稍微有些不同 configure enable gdb stub make make i
  • Java语言连接数据库时间读取错误的问题

    连接时候的数据库相关配置
  • pcie inbound和outbound关系

    Inbound PCI域訪问存储器域 Outbound 存储器域訪问PCI域 RC訪问EP RC存储器域 gt outbound gt RC PCI域 gt EP PCI域 gt inbound gt EP存储器域 EP訪问RC EP存储器
  • Jenkins插件下载失败两种处理办法

    持续集成 自动化部署 弹性伸缩教程 http edu csdn net course detail 6452 大家在使用jenkins安装插件的时候经常遇到一下问题 就是插件由于网络或者墙的原因无法直接下载 出现下面截图的问题 处理办法有两
  • flume采集log4j日志到kafka

    简单测试项目 1 新建Java项目结构如下 测试类FlumeTest代码如下 package com demo flume import org apache log4j Logger public class FlumeTest priv
  • 芯片电源引脚为什么要加一个100nF电容

    在设计电路的时候 常常会在芯片的每个电源引脚就近的放一个100nF的贴片电容 这电容有什么作用呢 今天就来和大家分享一下这个电容的作用以及为什么是100nF 首先这个芯片电源引脚的100nF的电容一般我们称为旁路电容 也有叫去耦电容的 因为
  • Oracle 行转列 动态出转换的列

    10月的第二天 前天写了个Oracle中行转列的pivot的基本使用方法 然后 因为pivot的用法中 正常情况下 我们需要转出多少个列 都得在我们的sql中完完整整地写出 而不能直接在里面写个查询来动态转换 然后 趁着祖国母亲的生日 这几