对于pivot和unpivot这个Oracle 11g的新功能一直就想总结一下,正好赶上论坛中有很多人会提问相关的问题,于是利用空闲时间翻译了一篇相关的网络文章。链接如下:

ITPuber:LuiseDalian翻译

时间:2012.11.29

1 Oracle 11g中的pivot和unpivot查询

转换查询包括将行转换成列(pivot)和将列转换成行(unpivot),从 而产生交叉表格式的结果。 转换是一项通用的技术,尤其对于报表来讲,正是由于该项技术使得多年来针对Oracle的不同版本,可以使用SQL语句产生转换查询的结果集。从 Oracle 11g开始,包含了显式的转换查询支持,即PIVOT和UNPIVOT关键字。这是对SELECT语句的扩展。

1.1 pivot

这里我们从pivot操作开始。大多数的开发者首先要熟悉转换数据:即多行被聚合,然后转换成列,每一列表示聚合数据的不同范围。语法:

除了新的pivot关键字外,可以看到3个新的pivot子句,描述如下:

 pivot_clause:定义被聚合的列(pivot是一种聚合操作)

 pivot_for_clause:定义被分组和转换的列。

 pivot_in_clause:定义pivot_for_clause子句中列的过滤器(例如使用值的范围来限制结果)。pivot_in_clause中每个值的聚合都将被转换成单独的列

1.1.1 一个简单的例子

这个例子是对pivot语法的简单的演示,使用scott.emp表,这里将通过department

和job来汇总salaries,然后转换对每个部门的汇总到它们各自的列上,在转换之前,先看一下基础数据

下面使用11g的语法来转换数据,对于每个job我们将sal的汇总,对每个部门使用单独一列。 可以看到对每个job按部门对sal的汇总已经变成了列,关于这个例子有几点需要注意,语法和结果:

 本例中的pivot_clause求sal列的和,如果需要可以指定多列和可选的别名。

 pivot操作执行隐式的GROUP BY,使用的列是没有出现在pivot_clause中的列(本例为job

和deptno)。大多数的转换查询都会在列的子集上进行操作,所以会使用存储视图、内联视图或子查询。

 这里的pivot_for_clause,表明我们只想转换deptno的聚合。

 这里的prvot_in_cluase,指明deptno值的范围,这里我们硬编码4个值的列表,这也是为什

么会产生4个转换列原因。如果省略别名,Oracle会使用pivot_in_clause中的值来产生转换后列的别名

如上所述,大多数的转换查询都在是列的特定的子集上来执行。像所有的聚合查询一样,额外列的出现会影响分组。这里只是通过在EMP表带有附加列的情况下进行转换查询,来确认这种影响。

在本例中,除了sal列,其余所有列都成了分组集,其中deptno为转换列。在本例中这个转换没有什么意义。

关于转换语法的非常有趣的一点是它在查询中的位置,即位于FROM和WHERE子句之间。 在下面的例子中,我们限制原来的转换查询在选择(通过添加谓词)出来的一些职位上进行。

上面的例子看起来好像是违反语感的,但是把谓词添加到pivot子句之前会产生语法错误。另外在我们的第1个例子中,我们是使用子查询部分(WITH语句)来定义基列的集合。我们可以使用内联视图(下例)或存储视图(后面的练习)来替代子查询。

1.1.2 给转换列指定别名

在前面的例子中,Oracle使用deptno列的值产生转换后列的名称,然而 我们可以给pivot_clause和pivot_in_clause中的一列或多列指定别名。通常Oracle将根据下面约定给转换列命名。 总结:就是pivot_in_clause中的列,如果指定别名就用别名,如果没有指定就用值;而pivot_cluaus中如果指定别名就连接到 pivot_in_cluase转换后的相应列的名称的后面,如果没有指定就不用。

5 / 41

下面将是这些别名选项的示例。我们已经做过没有任何别名的例子。为了简化起见,我们将输入数据集定义为视图。

给转换查询的所有元素指定别名。(Y, Y),Oracle将对应别名连接起来产生列名。

pivot_in_clause中的列不指定,pivot_clause中的列指定别名。(N, Y)

Oracle连接pivot_in_clause中的值和聚合列的别名产生列名。

只给

pivot_in_clause中的值指定别名。(Y,N),Oracle仅使用pivot_in_clause中的别名产生列名

总结:在所有的例子中pivot_in_clause用于所有的转换列的命名,不管我们是指定了值还是别名。因此,我们可以选择对哪些值指定别名。

1.1.3 转换多个列

目前为止,我们的例子都限制在一个聚合和一个转换列,然而我们可以定义多个。在下面的例子中将在pivot_clause中定义2个聚合,而对于deptno范围使用与前面的例子相同的值。新的聚合是对求和的薪水的计数。

这里得到的转换列是双倍(因为聚合的数量是双倍)。

转换列的数量 = 聚合列的数量 * pivot_in_clause中值的个数

下面的例子中,扩展了pivot_for_clause和pivot_in_clause。

这里限制查询30号部门中的3个职位。注意pivot_for_clause中的列(deptno, job)如何组合成一个转换维度。使用的别名应用了值域的组合(例,D30_SLS,代表30号部门的SALES)

因为我们已经知道了转换列的命名规则,所以我们可以直接引用它。

9 / 41

1.1.4 一般限制

对于理解转换查询有一些简单的陷阱。例,不能投影在 pivot_for_clause中使用的列(在前面的例子中为deptno列),这是预料之中的。在pivot_for_clause中的列会根据我们 在pivot_in_clause中提供的值的范围进行分组。下列中试图投影deptno列,Oracle引发ORA-00904异常,在这种情况 下,deptno完全从投影中被移除,并且Oracle可以告诉我们它在作用域中不存在。

10 / 41

同样也不能投影任何出现在pivot_clause中的列。这里试图投影sal列,引发了同样的异常。这也是可以预计到的:pivot_clause定义了查询中的聚合。因此这也意味着我们必须在pivot_clause中使用聚合函数。

下例中对于pivot_clause中的列没用使用聚合函数。引发ORA-56902异常。错误消息编号随着版本变化而越来越大。

1.1.5 转换操作的执行计划

像前面讲过的一样,转换操作隐式执行一个GROUP BY操作,但不需要我们指定它。我们可以通过解析我们前面的4个例子之一来确定这一点。为了方便我们将使用autotrace(它使用EXPLAIN PLAN和DBMS_XPLAN来显示推断出的执行计划)。

上面输出的执行计划告诉我们这个查询使用了HASH GROUP BY PIVOT操作。HASH GROUP BY是10gR2的功能,而PIVOT为11g的新功能。PIVOT查询不会自动产生PIVOT计划。

然而在下面的例子中,我们将限制pivot_in_clause中的值域并使用autotrace来再次解析查询。

这次CBO开销为一个简单的聚合,是通过使用pivot分组来完成的。它已经正确地识别出对于这个查询只有一条记录被返回,所以group by操作不是必须的。

最后我们将解析我们的第一个转换查询的例子,但是会使用DBMS_XPLAN的扩展格式化选项来获取Oracle所做的工作的更多的信息。

DBMS_XPLAN选择性地显示了包含在PLAN_TABLE表中的查询的每 一步的列的投影信息。 ID = 2的投影操作表明建立在EMP基表上的PIVOT_DATE视图中我们选择的基列。最有趣味的信息却是ID = 1(这一步是转换操作)。这里清楚地显示了Oracle是如何产生转换列的。许多开

发者对于这种形式的SQL很熟悉,这是我们在11g之前我们写转换查询的方法。Oracle 选择了case表达式,但我们通常是使用 decode函数。

1.1.6 pivot性能

从我们看到的种种迹象表明,好像Oracle使用已经被大家认可的SQL形式实 现了新的PIVOT语法。我们期望我们的转换查询有相同的性能,而不管我们使用的是哪种技术。(即11g pivot语法和sum(decode..)转换技术将执行相同的操作。我们将使用autotrace(通常的I/O模式)和wall-clock(花费 的时间)对大的数据集来测试我们的假设。首先,我们创建一个有100万行记录的表。

我们将比较这2个转换查询技术(在我们对表million_rows进行几次全扫描之后,避免结果具有随机性)。下面从Oracle 11g的新语法开始。

最重要的输出已经被用红色下划线标出。即整个查询用时为4.06

秒,产生大约

14000 的PIO和LIO。更有趣的是CBO针对这个volume的查询采用了基于HASH GROUP BY的SORT GROUP BY,计算了大约120万的记录(1115K)。

作为比较,我们将运行如下的11g之前的转换查询。

如果没有异常情况的话,该查询的时间和资源消耗的结果与新的pivot语法差不多。这就是我们所期望的。事实上,这种查询 的新的转换版本会产生更多的递归SQL,和更多的内存排序,但我们可以通过这个简单的测试得出结论,新的技术没有性能上的损失。下面我们将对转换更多的行 来验证这个结论。

SQL>set timing on

SQL> set autotrace traceonly statistics

WITH pivot_data AS

(

SELECT pivoting_col, grouping_col, summing_col

FROM million_rows

)

SELECT *

FROM pivot_data

PIVOT

(

SUM(summing_col) AS sum,

COUNT(summing_col) AS cnt,

AVG(summing_col) AS av,

MIN(summing_col) AS mn,

MAX(summing_col) AS mx

FOR pivoting_col IN (0,1,2,3)

)

ORDER BY grouping_col;

18 / 41

这个例子中会产生20个转换列,注意,上面的输出是例子第3次或第4次运行的输出,这样做是为了避免结果的交叉。最终I/O模式和消耗的时间与前面的4个例子是相同的,除了转换了额外的16列之外。下面将与使用SUM(DECODE…)技术进行比较。

SELECT grouping_col, SUM(DECODE(pivoting_col,0,summing_col)) AS "0_SUM", COUNT(DECODE(pivoting_col,0,summing_col)) AS "0_CNT", AVG(DECODE(pivoting_col,0,summing_col)) AS "0_AV",

MIN(DECODE(pivoting_col,0,summing_col)) AS "0_MN",

MAX(DECODE(pivoting_col,0,summing_col)) AS "0_MX",

SUM(DECODE(pivoting_col,1,summing_col)) AS "1_SUM", COUNT(DECODE(pivoting_col,1,summing_col)) AS "1_CNT", AVG(DECODE(pivoting_col,1,summing_col)) AS "1_AV",

MIN(DECODE(pivoting_col,1,summing_col)) AS "1_MN",

MAX(DECODE(pivoting_col,1,summing_col)) AS "1_MX",

SUM(DECODE(pivoting_col,2,summing_col)) AS "2_SUM", COUNT(DECODE(pivoting_col,2,summing_col)) AS "2_CNT", AVG(DECODE(pivoting_col,2,summing_col)) AS "2_AV",

MIN(DECODE(pivoting_col,2,summing_col)) AS "2_MN",

MAX(DECODE(pivoting_col,2,summing_col)) AS "2_MX",

SUM(DECODE(pivoting_col,3,summing_col)) AS "3_SUM", COUNT(DECODE(pivoting_col,3,summing_col)) AS "3_CNT", AVG(DECODE(pivoting_col,3,summing_col)) AS "3_AV", MIN(DECODE(pivoting_col,3,summing_col)) AS "3_MN",

MAX(DECODE(pivoting_col,3,summing_col)) AS "3_MX"

FROM million_rows

GROUP BY grouping_col

ORDER BY grouping_col;

19 / 41

我们开始看到了新的PIVOT语法是多么地方便,而且,尽管2个方法的工作量相差无几,但老的人工转换技术要比新技术慢很多啊(3.22<>11.75)(对于本例的多次运行,此外也运行了另外的使用CASE替代DECODE的版本)

1.1.7 转换值的未知域

到目前为止我们的例子都是转换值的已知的域,即我们在 pivot_in_clause中使用的是硬编码。我们使用的pivot语法,即默认的语法,不支持pivot_in_clause中动态的值列表。如果 我们在pivot_in_clause中使用一个子查询而不是一个列表,Oracle会产生异常。

许多开发者可能会认为这是一个主要的限制(而没有考虑到,事实上在11g之前的转换技术也是需要我们显式地编码值的集合)。这有可能产生未知的转换值的集合。记得在前面的简单的语法浏览中PIVOT支持XML这个可选关键字。就像关键字暗示的一样,这允许我们产生转换的结

20 / 41

果集,但是以XML格式提供的。作为它的扩展,我们可以为任何数量的转换列产生XML结果集,就像定义动态的pivot_in_clause一样。

使用XML扩展,我们有3个选项来产生pivot_in_clause:

 可以使用值的显式列表。(前面的例子一直是这样做的)

 在pivot_in_clause中使用ANY关键字,这意味着我们希望转换pivot_in_clause中列的所有

值。

 可以在pivot_in_clause中使用子查询来获取值的列表。

我们将集中精力于这些动态方法。下例中将使用ANY对数据库中DEPTNO列的所有值产生转换结果集。

XML结果集为XMLType类型,这意味着我们可以轻松地使用XPath或 Xquery表达式来操作它。可以看到产生的转换列的命名是根据pivot_clause而不是pivot_in_clause(记得在非XML查询 中,pivot_in_clause值或者是别名在所有的转换列的命名中起主要作用)。我们也可以看到XML列名本身是由 pivot_for_clause产生的:Oracle在DEPTNO后面附加了_XML。

下面我们重复前面的练习,但给privot_clause添加了一个别名。如果想将改变列名DEPTNO_XML,可以使用SQL标准别名。

建议pivot_clause别名定义了转换的XML元素的名称,而XML列名本身是通过投影别名来定义的。

对于ANY的一个替代的方法是使用子句。下面的例子中使用在DEPT表表上的查询来替代ANY,获取DEPTNO值的列表。

可以看到和使用ANY的关键区别是:当使用子查询方法时,Oracle对于子查 询返回的每个值产生一个转换后的XML元素(对于每个分组)。例如,ANALYST员工只工作于20号部门,因此ANY方法对于该部门返回一个转换XML 元素。然而子查询方法会产生4个XML元素(对于10, 20, 30, 40号部门),但只有20号部门是非空的。如果我们从2种pivot_in_cluase使用方法的结果中抽取薪水元素,将会看得更清楚。

使用ANY时只对20号部门产生一个XML元素,下面是使用子查询。

这里不管3个部门没有薪水的汇总,Oracle对每个产生一个空元素。只有20部门有薪水汇总。开发者选择哪种方法,依赖于实际的需求,但是要认识到使用XML会产生过多的数据集或结果集。在这方面,子查询方法可能潜在会产生比需要的结果集多得多的额外的数据。

1.2 unpivot

在前面已经详细浏览了11g 的pivot转换的功能。下面看一看新的unpivot操作符。像名称一样unpivot是pivot操作的逆操作(虽然不能反聚合数据)。简单的想法就 是它能将转换后的列转换成行(对于反转换的每一列产生一行数据)。下面是一些例子,在例子之前先看一下语法。

除了一些细微的差别外,基本上与pivot的语法类似,包括各个子句的含义。

 unpivot_clause:为表示反转换的计算值的列指定列的名称,在前面的转换的例子中,计算列

为对于每个job和department分组的汇总。

 unpivot_for_clause:指定反转换查询的结果列的名称。该列中的数据描述了unpivot_clause

中列的计算值。

 unpivot_in_clause:包含了即将被反转换的pivot操作后列的列表(不是值)

unpivot子句很难被描述清楚,最好通过一些例子来解释。

24 / 41

1.2.1 简单unpivot示例

在进行unpivot查询之前,先创建一个pivot操作后的结果集用于后面的练习。这里使用前面练习过的一个pivot查询。

pivoted_data视图中包含通过job进行分组的部门的薪水的和,记住这些数据的特征,后面将查询该视图。

下面使用11g的新语法进行unpivot操作

可以看到Oracle已经转换了每个在unpivot_in_cluase中的 列(它们是pivot操作的结果),把它们转换成了数据行,这些数据描述了我们的度量(例, D10_SAL, D20_SAL等等)。unpivot_for_clause给unpivovit操作后的结果列一个名称 (SALDESC);unpivot_clause本身定义了计算的数据,这里就是每个职位的部门薪水汇总。

注意:unpivot查询可以作用于任何例(不仅仅是聚合后的列或pivot操作后的列。这里使用pivot操作的结果集,目的是为了举例的连续性,实际上可以容易地对任何表任何视图的列进行unpivot操作。

1.2.2 处理空数据

一个unpivot查询可以返回的最大行数为:分组数 * 转换操作列(本文的示例中为5(jobs) * 4(转换列)。然而第一个unpivot练习只返回了9行。如果查看源pivot数据本身,在pivot列中只有9个非空数值。换言之,11个分组为空。 unpivot操作默认会排除null值。当然也有选项让结果包含这些空值。

26 / 41

通过包含NULL值,返回了可能从结果集获取的最大行数。当然,现在有11个空值,但这可能是为了报表或使数据更加严密的目的。

1.2.3 unpivot别名选项

在本文的pivot部分介绍了各种不同的别名选项。unpivot语法中也允许使用别名,但使用上更严格。事实上,只能给unpivot_in_clause中定义的列指定别名。

27 / 41

通过包含NULL值,返回了可能从结果集获取的最大行数。当然,现在有11个空值,但这可能是为了报表或使数据更加严密的目的。

1.2.3 unpivot别名选项

在本文的pivot部分介绍了各种不同的别名选项。unpivot语法中也允许使用别名,但使用上更严格。事实上,只能给unpivot_in_clause中定义的列指定别名。

27 / 41

这个练习表明在unpivot_in_cluase中使用类型转换也不是有效的语法,Oracle会相应地引发异常。因此一个变通的方案是使用内联视图、子查询或存储视图预先对列进行转换,下列中就是使用子查询方法。

29 / 41

由于篇幅原因,结果没有全部输出,

但可以看到对emp表中数据的unpivot操作的效果。(例如,有3个列进行unpivot操作,原始数据的行数为12行,因此输出36行记录)。

另一个限制是在unpivot_in_clause中的列,是不可以在unpivot_clause外进行投影操作的,下列是试图投影deptno列。

Oracle产生标识符无效的异常。

当我们投影出所有有效的列时就可以看出为什么会这样。

可以看出unpivot操作的列是不能不作为投影的一部分来使用的。

1.2.5 unpivot操作的执行计划

在前面的pivot查询的执行计划中,看到有GROUP BY PIVOT操作。在下面的例子中,使用autotrace来产生最后一个unpivot查询的执行计划。

感兴趣的点已经被加上了红色的下划线。首先看到了新的unpivot步骤 (ID=3);第2是一个Filter谓词移除了deptsal所有的NULL值,这是默认的EXCLUDING NULLS子句的结果。如果使用INCLUDING NULLS子句,则该过滤器被移除;注意,位于PIVOTED_DATE视图下面的GROUP BY PIVOT操作(ID=5)是由pivot查询产生的。

下面会使用DBMS_XPLAN的格式化选项来抽取更为详细的关于该执行计划的信息。特别要查看一下别名和投影的细节,看看是否提供了unpivot操作线索。

unpivot操作的列的投影是上面的1-3步操作。这并没有提供Oracle如何实现unpivot的细节。注意:10046跟踪也没有提供细节,所以本文并未提及10046跟踪。

别名的信息有些意思,但也没有告诉关于unpivot的信息。It might be a red herring。当Oracle转换一个简单查询的时,产生的查询块的别名通常跟一个后缀,例如"SEL$1", "SEL$2"等,在本例中的unpivot查询中别名非常大,像SEL$17,因此这是一个有很少组件的非常简单的查询。这可能是暗示在优化之前进行了 许多查询重写,只是不能从上面的细节得到确认。

1.2.6 unpivot的其它使用

unpivot查询不仅限于转置pivot操作后的数据。可以转换表的任何列的 集合(但数据类型必须满足约束)。Tom Kyte的print_table过程就是一个很好的例子。这个工具unpivot宽的记录,这样就可以读数据一直到页的底部,而不用交叉来读。新的 unpivot可以用来实现同样的目的。下例中写的是一个静态的unpivot查询,它与print_table工具类似。

34 / 41

1.2.7 11g之前的unpivot查询

在结束本文之前,将阐述几中11g之前的unpivot查询的技术并比较它们的性能。

第1种方法使用产生虚拟rowsource的笛卡尔乘积。rowsource具有进行unpivot操作的列数相同的行数。下面将使用前面unpivot示例相同的数据集进行说明。

这个结果与使用INCLUDING NULLS的unpivot操作的结果是一样的。

第2种技术是将pivot操作后的结果集与想转换的列的集合进行连接操作。

下例中使用普通的NUMBER_NTT嵌套表类型来保存被转换的部门薪水列。可以使用数据类型,因为所有的被转换的列都为NUMBER类型。

这里已经转换了部门的薪水,但却丢失了每个值班的描述性的标签。没有简单的方法来decode行号(像在笛卡尔乘积方法中一样)。然而却可以改变集合的类型来包含一个描述标签。为此,先创建一个通用对象类型来定义单个的数据转换数据行。

37 / 41

第37 / 41页

可以看出11g的unpivot语法比11g之前的替代方法列容易,下面将使用autotrace、花费的时间和million_rows测试表来比较这些方法的性能。下面从11g的开始,转换测试表中的3个数值列。 38 / 41

第38 / 41页

11g的unpivot方法用时1分32秒,产生300万行记录,比前面的pivot操作的逻辑I/O稍微多一些。下面将与笛卡尔乘积方法进行比较,但使用了rowsource技术不会产生额外的I/O(这里不是使用all_object视图)

39 / 41

第39 / 41页

笛卡尔乘积方法明显慢于11g的unpivot方法。它产生了更多的I/O,耗 时2倍多。然而研究SQL跟踪表明,额外的I/O是由于对临时表空间的直接读和直接写造成的,来支持大规模的内存排序。(例如,伴随着MERGE JOIN CARTESIAN操作的排序)。在大多数的商业系统中,这种内存排序可能完全运行于内存或访问更快的临时表空间。因为小的系统通常是慢速的磁盘访问,这 对于性能有很大影响。这里可以通过整体上强制嵌套循环连接或避免磁盘排序来进行优化。 40 / 41

第40 / 41页

这里已经在同一数据库上显著地降低了消耗的时间和I/O

,但却引入了100万的微排序。可以反向嵌套循环排序或使用NO_USE_MERGE指令,但这会加倍I/O并增加大约10%的时间消耗。 最后比较集合方法。

这个方法与unpivot相比,I/O方面差不多,但却慢了35%-40%。进一步研究SQL跟踪表明,增加的CPU时间花费在了集合的迭代获取上。因此unpivot操作是即容易编码,也比其它SQL替代方法更快。

41 / 41

oracle unpivot 索引_oracle 11g中的pivot和unpivot转换操作相关推荐

  1. oracle unpivot 索引_Oracle 行转列pivot 、列转行unpivot 的Sql语句总结

    这个比较简单,用||或concat函数可以实现 select concat(id,username) str from app_user select id||username str from ap ...

  2. oracle unpivot 索引_oracle 11g 行列转换之unpivot、pivot

    一.    列    转    行 create table STU_ROW2COL ( id      VARCHAR2(10), intname VARCHAR2(10), subject VAR ...

  3. oracle unpivot 索引_oracle pivot 和 unpivot 函数的使用

    pivot的格式 select from ( inner_query) pivot(aggreate_function for pivot_column in ( list of values)) o ...

  4. pivot for oracle,Oracle 11g 行列互换 pivot 和 unpivot 说明

    针对Oracle 11g 之前版本的行列转换,之前整理过一篇文档: 在Oracle 11g中,Oracle 又增加了2个查询:pivot 和 unpivot. pivot:行转列 unpivot:列转 ...

  5. oracle全局索引 前缀索引_Oracle数据库中的索引详解

    一. ROWID的概念 存储 了row在数据文件中的具体位置:64位编码的数据,A-Z, a-z, 0-9, +, 和 /, row在数据块中的存储 方式 SELECT ROWID, last_nam ...

  6. SQL Server 2008中的Pivot和UnPivot

    SQL Server 2008中SQL应用系列--目录索引 今天给新成员讲解PIVOT 和 UNPIVOT示例,顺便整理了一下其用法.这是自SQL Server 2005起提供的新功能. 官方示例:h ...

  7. oracle 手机客户端_Oracle 11g客户端

    Oracle 11g客户端是一款非常专业的数据库软件,它可以帮助企业管理企业信息.更深入地洞察业务状况并迅速自信地做出调整以适应不断变化的竞争环境.所以有需要的用户欢迎在WWW.11684.COM 下 ...

  8. oracle in 索引_Oracle 性能优化总结

    作者 | 帅性而为1号 出处 : https://blog.csdn.net/zhushuai1221/article/details/51740846 网上关于SQL优化的教程很多,但是比较杂乱.近 ...

  9. plsql口令过期_Oracle 11g中密码过期问题详解

    密码过期的原因一般有两种可能: 一.由于Oracle中默认在default概要文件中设置了"PASSWORD_LIFE_TIME=180天"所导致. 二.由于Oracle中默认在d ...

最新文章

  1. 【Bootstrap+JSP+Mysql学习笔记(二)】开发环境配置(二)
  2. eeglab中文教程系列(4)-预处理工具
  3. MySQL基本操作及乱码问题的解决方法
  4. HBase环境搭建与使用
  5. SAP Fiori Elements 概述
  6. python参数类型_Python 参数类型和参数匹配模型
  7. Android之AIDL服务
  8. php文字左右滚动代码,JavaScript
  9. fieldset ----- 不常用的HTML标签
  10. java swing复选框大小_Java Swing界面编程(28)---复选框:JCheckBox
  11. mysql 查找相似数据_局部敏感哈希LSH(Locality-Sensitive Hashing)——海量数据相似性查找技术...
  12. uniapp前端处理接口返回一整个html格式
  13. 程序员买房,买车,一个避不开的梗
  14. Unity学习笔记:unity脚本常用API
  15. The Dominant Color (20)
  16. vs code设置默认浏览器
  17. 尊严与爱——论《简爱》的价值观
  18. c语言输入一串字符统计各字母出现次数,统计输入字符各个字母出现频率的解题思路...
  19. 【环境配置】gazebo搭建仿真机器人研究动态障碍物算法
  20. Visual Studio Code最新1.66.0版下载

热门文章

  1. 问道游戏私人服务器架设+详细搭建教程+外网教程
  2. linux通配符优先级,Linux通配符
  3. 【干货】我是如何开发公司年会抽奖系统的?
  4. CS4:新一代SOC与态势感知大会 六家安全厂商分享核心解决方案
  5. Springboot 接口允许跨域访问
  6. 你可曾拥有过存钱罐(迭代器模式)
  7. GNONE桌面解除自动锁屏
  8. 基于STM32F103 0.96寸OLED液晶屏驱动(iic通讯)
  9. 计量经济学之回归分析学习笔记(均值回归、分位数回归、岭回归、Lasso回归、ENet回归)——基于R(一)
  10. oracle nvl函数 mysql_关于Oracle数据库中的nvl函数