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

推荐订阅源

博客园 - 三生石上(FineUI控件)
L
LangChain Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
T
Tailwind CSS Blog
T
The Blog of Author Tim Ferriss
U
Unit 42
B
Blog
N
Netflix TechBlog - Medium
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
O
OpenAI News
M
MIT News - Artificial intelligence
D
DataBreaches.Net
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LINUX DO - 热门话题
C
CERT Recently Published Vulnerability Notes
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News and Events Feed by Topic
Vercel News
Vercel News
T
Tenable Blog
Security Latest
Security Latest
C
Check Point Blog
云风的 BLOG
云风的 BLOG
PCI Perspectives
PCI Perspectives
月光博客
月光博客
TaoSecurity Blog
TaoSecurity Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Project Zero
Project Zero
雷峰网
雷峰网
IT之家
IT之家
H
Hacker News: Front Page
Microsoft Security Blog
Microsoft Security Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Last Week in AI
Last Week in AI
G
Google Developers Blog
Forbes - Security
Forbes - Security
The Register - Security
The Register - Security
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Martin Fowler
Martin Fowler
K
Kaspersky official blog
P
Proofpoint News Feed
T
Threatpost
Google Online Security Blog
Google Online Security Blog
Microsoft Azure Blog
Microsoft Azure Blog

博客园 - 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技术,可以轻松地处理复杂的数据集,并实现更高效的数据处理。

不足之处,还望见谅!