首页 > 数据库 >Oracle高级技巧:使用PIVOT函数和窗口函数解决只查询一条数据的问题

Oracle高级技巧:使用PIVOT函数和窗口函数解决只查询一条数据的问题

时间:2023-11-06 11:11:05浏览次数:42  
标签:dl 函数 dc 查询 Oracle PIVOT creatdate

写本博客的目为了温故而知新把学习过程记录下来,以备后查。

当我们需要将表格中的行转置为列时,通常可以使用PIVOT函数来实现。但是在某些情况下,由于创建日期等字段相同,只有一条数据会被查询出来。这时候,我们就可以使用窗口函数进行分组和排序,以便返回具有相同创建日期的所有记录。本文将介绍如何通过使用PIVOT函数和窗口函数,解决只查询一条数据的问题。

行转列:使用PIVOT函数

在SQL查询中,行转列通常使用PIVOT函数来实现。PIVOT函数能够将行数据转换为列数据。例如,以下是从表格中选择半成品批号、日期、组次和重量列的查询:

1 SELECT Lot, Date, Group, Weight
2 FROM myTable 
View Code

使用PIVOT函数后的查询语句如下:

1 SELECT *
2 FROM myTable
3 PIVOT (MAX(Weight) FOR [Date] IN ([2022-01-01], [2022-01-02], [2022-01-03])) AS pTable
View Code

在上面的语句中,使用了MAX函数将重量作为聚合值,并使用[Date]列作为PIVOT的转置列。在转置列中,我们可以指定需要转置的值,例如[2022-01-01]、[2022-01-02]、[2022-01-03]等。如果不指定这些值,则PIVOT函数将根据原始数据自动生成列。

creatdate时间一样,只查询一条数据

然而,在某些情况下,由于创建日期等字段相同,只有一条数据会被查询出来。例如,以下查询语句只返回最新创建日期的一条数据:

1 SELECT *
2 FROM myTable
3 WHERE Lot = '3IA270' AND Group = '91'
4 ORDER BY creatdate DESC
View Code

在这种情况下,我们可以通过使用窗口函数来解决查询结果只包含一条数据的问题。

使用窗口函数解决查询一条数据的问题

窗口函数是一种高级SQL技术,它可以对行数据进行排序和分组,并为每个行数据分配一个序号。以下是一个使用窗口函数的示例查询:

1 SELECT *
2 FROM (
3   SELECT *, ROW_NUMBER() OVER (PARTITION BY Lot, Group ORDER BY creatdate DESC) AS rn
4   FROM myTable
5 ) X
6 WHERE Lot = '3IA270' AND Group = '91' AND rn = 1
View Code

在这里,我们使用了窗口函数ROW_NUMBER()来对每个半成品批号和组次分组,并根据创建日期降序排列。然后,在外部SELECT语句中,我们仅保留rn值为1的记录,以确保每个半成品批号和组次只返回最新的一条数据。

 我们来看看真实的操作语句,一下是原始实例查询语句与查询结果:

 1 select t.*
 2   from (
 3   select  dc.datacollectiondefname,dl.dataname,dl.datavalue,dl.creatdate 
 4   from  datapointhistorydetail  dl,datacollectiondef df ,datacollectiondefbase dc
 5   where  dl.datacollectiondefid=df.datacollectiondefid
 6   and df.datacollectiondefbaseid=dc.datacollectiondefbaseid
 7   and dc.datacollectiondefname = 'DropEnzymeWeight')X pivot 
 8   (
 9     max(datavalue) for dataname in (
10     'Lot' as 半成品批号,
11     'Date' as 日期,
12     'Class' as 班别,
13     'Group' as 组次,
14     'DroppingEnzymePlatformNo' as 滴酶平台编号,
15     'ScaleNumber' as  天平编号,
16     'Time' as 时间,
17     'SlidesNo' as 片号,
18     'Weight' as 重量,
19     'Judge' as 判断,
20     'Operator' as 操作人,
21     'OperateDate' as 操作日期,
22     'Exception' as 异常情况,
23     'Recorder' as 记录人,
24     'Checker' as 复核人
25     )
26 ) t where  t.半成品批号='3IA270' and t.组次='91'
27 order by creatdate desc 
View Code

 在Oracle中,如果需要查询具有相同创建日期的所有数据,即使时间相同,可以通过在窗口函数中添加序号,并根据序号筛选出需要的数据。以下是修改后的查询语句:

 1 SELECT t.*
 2 FROM (
 3   SELECT dc.datacollectiondefname, dl.dataname, dl.datavalue, dl.creatdate, 
 4          ROW_NUMBER() OVER (PARTITION BY dl.datacollectiondefid, dl.dataname, dl.creatdate ORDER BY dl.creatdate DESC) AS rn
 5   FROM datapointhistorydetail dl, datacollectiondef df, datacollectiondefbase dc
 6   WHERE dl.datacollectiondefid = df.datacollectiondefid
 7     AND df.datacollectiondefbaseid = dc.datacollectiondefbaseid
 8     AND dc.datacollectiondefname = 'DropEnzymeWeight'
 9 ) X PIVOT (
10   MAX(datavalue) FOR dataname IN (
11     'Lot' AS 半成品批号,
12     'Date' AS 日期,
13     'Class' AS 班别,
14     'Group' AS 组次,
15     'DroppingEnzymePlatformNo' AS 滴酶平台编号,
16     'ScaleNumber' AS 天平编号,
17     'Time' AS 时间,
18     'SlidesNo' AS 片号,
19     'Weight' AS 重量,
20     'Judge' AS 判断,
21     'Operator' AS 操作人,
22     'OperateDate' AS 操作日期,
23     'Exception' AS 异常情况,
24     'Recorder' AS 记录人,
25     'Checker' AS 复核人
26   )
27 ) t 
28 WHERE t.半成品批号 = '3IA270' AND t.组次 = '91' --AND t.rn = 1
29 ORDER BY creatdate DESC 
View Code

 

结论

本文介绍了如何使用PIVOT函数和窗口函数,将表格中的行数据转置为列数据,并解决只查询一条数据的问题。通过这些高级SQL技术,可以轻松地处理复杂的数据集,并实现更高效的数据处理。

 

不足之处,还望见谅!

 

标签:dl,函数,dc,查询,Oracle,PIVOT,creatdate
From: https://www.cnblogs.com/zengzhanping/p/17812231.html

相关文章

  • '/webhook'​​​是你的服务器上的一个路径,当有人发送POST请求到这个路径时,​​webhoo
    在这段代码中,'/webhook'是你的服务器上的一个路径,当有人发送POST请求到这个路径时,webhook()函数就会被调用。你可以根据你的需求来选择这个路径,只要它在你的服务器上是唯一的。例如,如果你的服务器的URL是http://myserver.com,那么当飞书机器人发送POST请求到http://myserver.com/web......
  • 无涯教程-批处理 - CLS函数
    此批处理命令清除屏幕。CLS-语法clsCLS-示例@echooffCls命令提示符屏幕将被清除。参考链接https://www.learnfk.com/batch-script/batch-script-cls.html......
  • 在Winform中通过LibVLCSharp回调函数获取视频帧
    参考资料:VlcVideoSourceProvider优点:实现视频流的动态处理。缺点:视频解码(CPU/GPU)后图像处理CPU占用率高。在Winform中通过LibVLCSharp组件获取视频流中的每一帧图像,需要设置回调函数,主要是SetVideoFormatCallbacks和SetVideoCallbacks,其定义如下所示:///<summary>///Setde......
  • std::sort 传入成员函数指针报错的解决方案
    问题引入有一个类A,A的某个成员函数需要对A的某些变量进行std::sort,同时要调用A的另一个成员函数作为比较器。如代码所示:structA{vector<int>pos={0,4,2,5,3};boolcmp(intx,inty){returnpos[x]<pos[y];}voiddemo(){vector<int>a={2......
  • 小白函数递归------新手
    1.递归是什么?递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。 #include<stdio.h>voidprint(){ printf("hehe"); print();}intmain(){ printf("hehe"); print();}在上面的函数中函数实现了自己调用自己,去实现我们想要去实现的功能,这种就是函数......
  • C++_15_友元函数和友元类 - 重写版
    友元函数和友元类友元函数:通过friend关键字,将不属于当前类的函数在当前类中加以声明,使其成为友元函数,同时该函数能够访问private属性的成员变量。友元类:有有元函数,自然也能有友元类,通过friend关键字,将类A在类B中声明,那么类A会成为类B的友元类注意:1、友......
  • C++_20_操作符重载和函数重载 - 重写版
    操作符(运算符)重载 操作符重载指的是将C++提供的操作符进行重新定义或者多重定义,使之满足我们所需要的一些功能。在C++中,经常有需要对多个对象进行算术运算,但是对象比不是基本的数据类型,所以这些运算符都无法执行。为了让程序识别这些运算符,就需要对运算符进行重载......
  • C++_19_虚函数、纯虚函数和抽象类 - 重写版
    虚(成员)函数:在C++中,只有类中的成员函数能被声明为虚函数,顶层函数则不能被声明为虚函数;并且如果在类内声明类外定义,则只在类内声明时加virtual声明虚函数是为了构成多态,多态需要继承关系,需要在类中声明;虚函数能被继承:基类被声明为虚函数,那么派生类即便未添......
  • C++_25_函数模板和类模板 - 重写版
    模板:在C++中允许函数重载,但函数重载每次都必须完全对上参数的顺序,类型和数量。所以C++提供了另一种代码重用机制——“模板”,可以作为同一种类型函数的统一调用接口。模板机制下可划分:1、函数模板      2、类模板模板的语......
  • 函数剩余参数与 展开运算符
    //剩余参数functionsum(...arr){console.log(arr)}sum(3,4,5,6)//求数组最大值letarr=[1,44,7,88]console.log(Math.max(...arr))......