惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
罗磊的独立博客
J
Java Code Geeks
博客园_首页
量子位
腾讯CDC
阮一峰的网络日志
阮一峰的网络日志
Jina AI
Jina AI
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
Cloudbric
Cloudbric
Last Week in AI
Last Week in AI
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
IT之家
IT之家
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cybersecurity and Infrastructure Security Agency CISA
L
Lohrmann on Cybersecurity
爱范儿
爱范儿
月光博客
月光博客
Spread Privacy
Spread Privacy
T
Tailwind CSS Blog
C
CERT Recently Published Vulnerability Notes
S
Schneier on Security
V
Vulnerabilities – Threatpost
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
Simon Willison's Weblog
Simon Willison's Weblog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 司徒正美
The Cloudflare Blog
G
GRAHAM CLULEY
I
Intezer
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
P
Privacy International News Feed
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
Engineering at Meta
Engineering at Meta

博客园 - CreativeSpirit

VS2015卸载过程实录 C# Body为form-data file文件上传至第三方接口 .NET WebAPI 控制器巧用 GroupName,让 Swagger UI 分类呈现华丽升级 VB.NET实现一键触发另一个窗体按钮点击事件的妙招 VB.net开发必备技能——两个窗体之间的数据传递方法! 掌握VB.net编程技巧,轻松打造Windows应用 TRUEmanager软件开发与维护指南 SQL Server 中的二进制转十进制函数编写 web录音——上传录音文件 CEF与JavaScript交互读取电脑信息 CefSharp.WinForms WPF开源框架项目 WPF入门教程系列四 2018年我的第一次年终总结 WPF入门教程系列三 c#串口开发WPF入门教程系列二 WPF入门教程系列一 C#串口通信程序实现无感知签到与答题 C# 调用adb command 读取手机型号和IMEI
Oracle高级技巧:使用PIVOT函数和窗口函数解决只查询一条数据的问题
CreativeSpirit · 2023-11-06 · via 博客园 - CreativeSpirit

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

当我们需要将表格中的行转置为列时,通常可以使用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技术,可以轻松地处理复杂的数据集,并实现更高效的数据处理。

不足之处,还望见谅!