【SQL边干边学系列】07高级问题-3

文章目录

  • 前言
  • 回顾
  • 高级问题
    • 41.逾期订单
    • 42.逾期订单-哪些员工?
    • 43.逾期订单与总订单相比
    • 44.逾期订单与总订单相比 - 丢失的员工
    • 45.逾期订单与总订单相比 - 修复null
    • 46.逾期订单与总订单之间的百分比
    • 47.逾期订单与总订单相比 - 修正decimal
  • 答案
    • 41.逾期订单
    • 42.逾期订单-哪些员工?
    • 43.逾期订单与总订单相比
    • 44.逾期订单与总订单相比 - 丢失的员工
    • 45.逾期订单与总订单相比 - 修复null
    • 46.逾期订单与总订单之间的百分比
    • 47.逾期订单与总订单相比 - 修正decimal
  • 未完待续


前言

在这里插入图片描述
该系列教程,将会从实际问题出发,边干边学,逐步深入讲解SQL的各方面知识。

你需要完成所有的问题吗?绝对不是。介绍性的问题相当简单,所以你可以直接跳过到“中级问题”部分。如果你不是初学者,但不确定应该从哪里开始,请在“入门问题”部分看看问题和预期结果,并确保你理解这些概念。如果已经理解了这些概念,请开始阅读“中级问题”部分。

你想从这本书中复制代码并在你的服务器上运行?我建议你手动输入,而不是复制粘贴。为什么要去麻烦地重新打字呢?科学表明,打字的行为会在你的脑中留下更深刻的印象。当你只是复制和粘贴时,代码只是直接从你电脑里的一个窗口转到另一个窗口,而不会给你留下多少印象。但是当你把它打出来时,你必须集中精力,这非常有助于保留信息。

一旦你完成了所有的问题,将拥有一些在数据分析和高级Select语句使用方面非常有用的技能。当然,这并不是SQL的全部内容。还有修改数据(更新、插入、删除)、DDL(数据定义语言,即如何创建和修改数据库对象)、编程(如存储过程)和许多其他主题。

该系列教程中,只涉及到了使用Select语句检索数据的问题,这几乎是所有其他数据库主题的基础开端。


回顾

上篇文章👉《【SQL边干边学系列】06高级问题-2》 开始讨论高级问题,这篇我们接着讨论。


高级问题

41.逾期订单

一些客户抱怨他们的订单迟到了。哪些订单迟到了?

-- 预期结果
OrderID     OrderDate  RequiredDate ShippedDate
----------- ---------- ------------ -----------
10264       2014-07-24 2014-08-21   2014-08-23
10271       2014-08-01 2014-08-29   2014-08-30
10280       2014-08-14 2014-09-11   2014-09-12
10302       2014-09-10 2014-10-08   2014-10-09
10309       2014-09-19 2014-10-17   2014-10-23
10380       2014-12-12 2015-01-09   2015-01-16
10423       2015-01-23 2015-02-06   2015-02-24
10427       2015-01-27 2015-02-24   2015-03-03
10433       2015-02-03 2015-03-03   2015-03-04
10451       2015-02-19 2015-03-05   2015-03-12
10483       2015-03-24 2015-04-21   2015-04-25
10515       2015-04-23 2015-05-07   2015-05-23
......
10970 2016-03-24 2016-04-07 2016-04-24
10978 2016-03-26 2016-04-23 2016-04-23
10998 2016-04-03 2016-04-17 2016-04-17
(39 row(s) affected)

提示:要确定哪些订单会延迟,可以组合使用RequiredDate和ShippedDate。如果ShippedDate实际上已经晚于RequiredDate,你可以确定它已经晚了。

42.逾期订单-哪些员工?

有些销售人员逾期的订单比其他人多。也许他们没有跟进订购流程,需要更多的培训。哪些销售人员的订单逾期最多?

-- 预期结果
EmployeeID  LastName             TotalLateOrders
----------- -------------------- ---------------
4           Peacock              10
3           Leverling            5
8           Callahan             5
9           Dodsworth            5
7           King                 4
2           Fuller               4
1           Davolio              3
6           Suyama               3
(8 row(s) affected)

提示:上面这个问题的答案是一个很好的起点。你需和“ Employee”表Join以获得last name,并添加“Count”来显示逾期订单总数。

43.逾期订单与总订单相比

仅仅查看每个销售人员逾期的订单数量并不是一个好主意。它需要与每个销售人员的订单总数进行比较。返回如下结果:

-- 预期结果
EmployeeID  LastName             AllOrders   LateOrders
----------- -------------------- ----------- -----------
1           Davolio              123         3
2           Fuller               96          4
3           Leverling            127         5
4           Peacock              156         10
6           Suyama               67          3
7           King                 72          4
8           Callahan             104         5
9           Dodsworth            43          5
(8 row(s) affected)

提示如下

你可以在一个查询中使用多个CTE。这将是解决这个问题的一种直接的方法。

下面是2个SQL语句,它们可以放入CTE中,并一起放入最终的SQL语句中。

-- Late orders
SelectEmployeeID,TotalOrders = Count(*)
From Orders 
WhereRequiredDate <= ShippedDate
Group ByEmployeeID
-- Total orders
SelectEmployeeID,TotalOrders = Count(*)
From Orders 
Group ByEmployeeID

44.逾期订单与总订单相比 - 丢失的员工

在上面这个问题的答案中缺少了一个员工。修复SQL,以显示所有已接受订单的员工。

-- 预期结果
EmployeeID  LastName              AllOrders  LateOrders
----------- -------------------- ----------- -----------
1           Davolio              123         3
2           Fuller               96          4
3           Leverling            127         5 
4           Peacock              156         10
5           Buchanan             42          NULL
6           Suyama               67          3
7           King                 72          4
8           Callahan             104         5
9           Dodsworth            43          5
(9 row(s) affected)

提示:当你只运行 AllOrders CTE时,返回了多少行?如果你只运行LateOrders CTE,返回了多少行?应该添加一个左连接(也称为左外部连接),以确保我们显示每一行,即使没有逾期订单。

45.逾期订单与总订单相比 - 修复null

继续上面查询的答案,让我们修复第5行的结果。在逾期订单中应该有0而不是null。

-- 预期结果
EmployeeID  LastName              AllOrders  LateOrders
----------- -------------------- ----------- -----------
1           Davolio              123         3
2           Fuller               96          4
3           Leverling            127         5 
4           Peacock              156         10
5           Buchanan             42          0
6           Suyama               67          3
7           King                 72          4
8           Callahan             104         5
9           Dodsworth            43          5
(9 row(s) affected)

提示:找到一个函数来测试一个值是否为空,并在该值为null时返回一个不同的值。

46.逾期订单与总订单之间的百分比

现在我们想知道逾期订单占总订单的比例。

-- 预期结果
EmployeeID  LastName              AllOrders  LateOrders  PercentLateOrders
----------- -------------------- ----------- ----------- -------------------
1           Davolio              123         3           0.0243902439024
2           Fuller               96          4           0.0416666666666
3           Leverling            127         5           0.0393700787401
4           Peacock              156         10          0.0641025641025
5           Buchanan             42          0           0.0000000000000
6           Suyama               67          3           0.0447761194029
7           King                 72          4           0.0555555555555
8           Callahan             104         5           0.0480769230769
9           Dodsworth            43          5           0.1162790697674
(9 row(s) affected)

提示如下

通过将逾期订单除以总订单,应该能够得到百分比。然而,人们会遇到一个常见的问题,即一个整数除以一个整数返回一个整数。例如,如果运行这条SQL:select 3/2,你将得到1而不是1.5,因为它将返回最接近的整数。

47.逾期订单与总订单相比 - 修正decimal

为了使输出更容易读取,我们让百分比字段保留2位小数。

-- 预期结果
EmployeeID  LastName              AllOrders  LateOrders  PercentLateOrders
----------- -------------------- ----------- ----------- -------------------
1           Davolio              123         3           0.02
2           Fuller               96          4           0.04
3           Leverling            127         5           0.04
4           Peacock              156         10          0.06
5           Buchanan             42          0           0.00
6           Suyama               67          3           0.04
7           King                 72          4           0.06
8           Callahan             104         5           0.05
9           Dodsworth            43          5           0.12
(9 row(s) affected)

提示如下

一种简单的方法是显式地将PercentageLateOrders转换为特定的Decimal类型。使用Decimal类型,您可以指定小数点右侧的位数。

计算PercentLateOrders变得有点长和复杂,要使所有的逗号和括号都正确可能很棘手。

简化它的一种方法是用一个实际的值进行验证。例如:

Select convert(decimal(10,2), 0.0243902439024)

答案

41.逾期订单

答案

SelectOrderID ,OrderDate = convert(date, OrderDate),RequiredDate = convert(date, RequiredDate),ShippedDate = convert(date, ShippedDate)
From Orders 
WhereRequiredDate <= ShippedDate

42.逾期订单-哪些员工?

答案

SelectEmployees.EmployeeID,LastName,TotalLateOrders = Count(*)
From Orders Join Employeeson Employees.EmployeeID = Orders.EmployeeID
WhereRequiredDate <= ShippedDate
Group ByEmployees.EmployeeID,Employees.LastName
Order by TotalLateOrders desc

讨论

请注意,“Employees”表中的LastName和EmployeeID都需要包含在Group by子句中,否则我们将得到错误信息。

从技术上讲,EmployeeID是一个主键字段,由于我们已经按其进行分组,只有一个LastName与EmployeeID相关联。但是,数据库引擎并不知道这一点,并且仍然需要在 Group by子句中包含LastName。

43.逾期订单与总订单相比

答案

;With LateOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders WhereRequiredDate <= ShippedDateGroup ByEmployeeID
)
, AllOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders Group ByEmployeeID
)
SelectEmployees.EmployeeID,LastName,AllOrders = AllOrders.TotalOrders,LateOrders = LateOrders.TotalOrders
From EmployeesJoin AllOrders on AllOrders.EmployeeID = Employees.EmployeeIDJoin LateOrderson LateOrders.EmployeeID = Employees.EmployeeID

讨论

上面的查询几乎是正确的,但是如果你仔细注意,你会意识到它有一个小问题。我们将在下一个问题中了解到更多信息。

44.逾期订单与总订单相比 - 丢失的员工

答案

;With LateOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders WhereRequiredDate <= ShippedDateGroup ByEmployeeID
)
, AllOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders Group ByEmployeeID
)
SelectEmployees.EmployeeID,LastName,AllOrders = AllOrders.TotalOrders,LateOrders = LateOrders.TotalOrders
From EmployeesJoin AllOrders on AllOrders.EmployeeID = Employees.EmployeeIDLeft Join LateOrderson LateOrders.EmployeeID = Employees.EmployeeID

讨论

如果我们展示所有的员工(包括那些没有订单的员工),我们需要使用左连接。

45.逾期订单与总订单相比 - 修复null

答案

;With LateOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders WhereRequiredDate <= ShippedDateGroup ByEmployeeID
)
, AllOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders Group ByEmployeeID
)
SelectEmployees.EmployeeID,LastName,AllOrders = AllOrders.TotalOrders,LateOrders = IsNull(LateOrders.TotalOrders, 0)
From EmployeesJoin AllOrders on AllOrders.EmployeeID = Employees.EmployeeIDLeft Join LateOrderson LateOrders.EmployeeID = Employees.EmployeeID

讨论

在LateOrder上直接使用IsNull是解决这个问题的最佳方法。

另一种写方法是使用Case语句:

LateOrders =CaseWhen LateOrders.TotalOrders is null Then 0Else LateOrders.TotalOrdersEnd

但是,当你除了测试null之外不需要任何其他逻辑时,IsNull是最好的方法。

46.逾期订单与总订单之间的百分比

答案

;With LateOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders WhereRequiredDate <= ShippedDateGroup ByEmployeeID
)
, AllOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders Group ByEmployeeID
)
SelectEmployees.EmployeeID,LastName,AllOrders = AllOrders.TotalOrders,LateOrders = IsNull(LateOrders.TotalOrders, 0),PercentLateOrders =(IsNull(LateOrders.TotalOrders, 0) * 1.00) / AllOrders.TotalOrders
From EmployeesJoin AllOrders on AllOrders.EmployeeID = Employees.EmployeeIDLeft Join LateOrderson LateOrders.EmployeeID = Employees.EmployeeID

讨论

如果你只是添加一个字段:

PercentLateOrders = LateOrders.TotalLateOrders/AllOrders.TotalOrders

所有字段都会得到0,尽管这显然是不正确的。但这就是当你把两个整数除在一起时所发生的情况。你需要将其中一个转换为decimal。转换为decimal数据类型的一种常见方法是乘以1.00。

请注意,在进行除法之前,你需要将整数转换decimal。如果你在除法之后做,就像这样:

(IsNull(LateOrders.TotalOrders, 0) / AllOrders.TotalOrders) * 1.00

你仍然会得到0。

47.逾期订单与总订单相比 - 修正decimal

答案

;With LateOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders WhereRequiredDate <= ShippedDateGroup ByEmployeeID
)
, AllOrders as (SelectEmployeeID,TotalOrders = Count(*)From Orders Group ByEmployeeID
)
SelectEmployees.EmployeeID,LastName,AllOrders = AllOrders.TotalOrders,LateOrders = IsNull(LateOrders.TotalOrders, 0),PercentLateOrders =Convert(Decimal (10,2),(IsNull(LateOrders.TotalOrders, 0) * 1.00) / AllOrders.TotalOrders)
From EmployeesJoin AllOrders on AllOrders.EmployeeID = Employees.EmployeeIDLeft Join LateOrderson LateOrders.EmployeeID = Employees.EmployeeID

讨论

四舍五入、截断和转换数据类型可能会变得复杂,而且有很多方法可能获得意想不到的结果。一定要仔细检查你的结果,并知道你是想要舍入,还是想要截断。

你可能已经注意到,我在计算中添加了一些新的行,以使它更容易阅读。这并不是必要的,但这是一种很好的编程实践,它更容易阅读和进行故障排除。


未完待续

下一篇我们接着讲剩余的高级问题。


如果喜欢这篇文章,请不要忘记关注🧡、点赞👍和收藏📔哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/26409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux - 复盘一次句柄数引发的故障

文章目录 Pre&#xff08;内核、用户、进程&#xff09;句柄数设置问题 shell修复 Pre Linux - 深入理解/proc虚拟文件系统&#xff1a;从基础到高级 &#xff08;内核、用户、进程&#xff09;句柄数设置 在Linux系统中&#xff0c;进程打开的最大句柄数可以通过多种方式配置…

第二证券:大牛股连续七跌停,上市公司坐不住了!机构抄底

6月12日&#xff0c;沪深股市双双飘红。但是&#xff0c;从前的大牛股松炀资源(603863)&#xff0c;却依然跌停收盘。这也是公司股价近日来的接连第七个跌停板。 龙虎榜显现&#xff0c;6月12日&#xff0c;松炀资源全天换手率10.38%&#xff0c;成交额3.45亿元。当天&#xf…

沉降观测点的定义、重要性、建设与选择

沉降观测点&#xff0c;简称沉降点&#xff0c;是指在建筑物、构筑物或地基等结构物上设置的用于测量其垂直位移(沉降)的特定位置。这些点通常被标记并安装相应的监测设备&#xff0c;以便长期、连续地监测结构物的沉降情况。 点击输入图片描述&#xff08;最多30字&#xff09…

python接入汇率换算工具提高网站/小程序日活度

实时汇率换算工具可以帮助用户快速准确地计算不同货币之间最新的汇兑比例。无论是金融从业者或者是人们日常生活出行都会使用到&#xff0c;广泛用于国际结算、银行汇率查询应用、开展跨国贸易、投资等参考场景。 我们可以通过在网站或者小程序中接入这样一个小工具&#xff0…

【Ardiuno】实验ESP32单片机自动配置Wifi功能(图文)

这里小飞鱼按照ESP32的示例代码&#xff0c;实验一下wifi的自动配置功能。所谓的自动配置&#xff0c;就是不用提前将wifi的名称和密码写到程序里&#xff0c;这样可以保证程序在烧录上传后&#xff0c;可以通过手机端的软件来进行配置&#xff0c;可以避免反复修改代码&#x…

ChromeOS 逐渐靠近安卓

ChromeOS 逐渐 “安卓化” 谷歌在博客中透露&#xff0c;将在ChromeOS底层更广泛地使用和Android相同的技术栈。一个具体的例子是&#xff0c;ChromeOS现在已经开始使用Android的蓝牙协议栈&#xff0c;取代了之前使用的自己的协议栈。这次改变不仅提高了蓝牙配对速度&#xf…

Postman下发流表至Opendaylight

目录 任务目的 任务内容 实验原理 实验环境 实验过程 1、打开ODL控制器 2、网页端打开ODL控制页面 3、创建拓扑 4、Postman中查看交换机的信息 5、L2层流表下发 6、L3层流表下发 7、L4层流表下发 任务目的 1、掌握OpenFlow流表相关知识&#xff0c;理解SDN网络中L…

【vue-8】记事本案例

小知识点&#xff1a; 列表末尾插入数据&#xff1a; list.push("lihua") 列表删除数据&#xff1a; # index要删除数据的索引值&#xff0c;1为删除数据长度 list.splice(index,1) 完整示例代码&#xff1a; <!DOCTYPE html> <html lang"en&quo…

R语言ggHoriPlot包绘制地平线图

数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 关键词“地平线图” 1. 数据读取与处理 首先&#xff0c;从TSV文件中读取数据&#xff0c;并进行数据清洗和处理。 rm(listls()) pacman::p_load(tidyverse,ggalt,ggHoriPlot,hrbrthemes…

教程:A5000 GPU 上运行阿里最新开源大模型 Qwen2

这是我们新一篇关于大模型的文章&#xff0c;我们此前还讲过如何运行 LLama3 大模型。而这次&#xff0c;我们将使用 Ollama 运行阿里千问Qwen2:7b。要知道 Qwen2 可是目前最热门的开源大语言模型了&#xff0c;甚至在一些性能测试中比 LLama3 表现还突出。谁不想试试看呢&…

C#下WinForm多语种切换

这是应一个网友要求写的&#xff0c;希望对你有所帮助。本文将介绍如何在一个WinForm应用程序中实现多语种切换。通过一个简单的示例&#xff0c;你将了解到如何使用资源文件管理不同语言的文本&#xff0c;并通过用户界面实现语言切换。 创建WinForm项目 打开Visual Studio&a…

最新下载:XmanagerXShell【软件附加安装教程】

​XManager企业版是一款完整的企业网络连接套件&#xff0c;它配备了一个高性能的PC服务器&#xff0c;安全终端模拟器&#xff0c;是一个一体化的解决方案&#xff0c;将xmanager&#xff0c;xshell&#xff0c;xftp&#xff0c;xlpd&#xff0c;Xbrowser及xstart放置在一个软…

C#发送邮件

C#发送邮件代码&#xff0c;亲测可用。 using System; using System.Net; using System.Net.Mail;namespace MailSend {class Program{static void Main(string[] args){try{MailAddress receiver new MailAddress("666666666qq.com");//666666666qq.com 换成收件人…

从零开始手把手Vue3+TypeScript+ElementPlus管理后台项目实战十(整体布局03之界面美化)

删除style.css 删除style.css(和main.ts同级) 并且注释掉main.ts中对style.css的导入。 修改App.vue 添加样式设置高度100% 安装sass pnpm install -D sass修改PageSidebar.vue 修改index.vue 修改src/layout/index.vue src/layout/index.vue添加样式 <style lang&quo…

09_探索时间序列的秘密:重新理解LSTM网络

1.1 简介 LSTM&#xff0c;全称为长短期记忆网络&#xff08;Long Short-Term Memory&#xff09;&#xff0c;是一种特殊的循环神经网络&#xff08;RNN&#xff09;结构&#xff0c;由Sepp Hochreiter和Jrgen Schmidhuber在1997年提出。它的设计初衷是为了克服传统RNN在处理…

tmega128单片机控制的智能小车设计

第1章 绪论1.1 选题背景和意义 自第一台工业机器人诞生以来,机器人的民展已经遍及机械、电子、冶金、交通、宇航、国防等领域。近年来机器人的智能水平不断提高,并且迅速地改变着人们的生活方式。人们在不断探讨、改造、认识自然的过程中,制造能替代人工作的机器一…

Linux常用基本命令-操作

目录 一、shell 1、什么是shell 二、Linux基本的命令分类 1、内部命令和外部命令 2、查看内部命令 2.1、help命令 2.2、enable 命令 2.3、type命令 2.4、whereis命令 2.5、which 命令 2.6、hash缓存 ​编辑 三、Linux常用命令 1、Linux命令格式 2、编辑Linux命…

服务端渲染 SSR 原理和实现

文章目录 CSR 优缺点SSRServer Client 同构Hydrate 水合&#xff08;客户端激活&#xff09;数据的获取和初始化预加载资源避免应用单例避免全局副作用代码 CSR 优缺点 优点 整个网站打包进 JavaScript 里&#xff0c;当 JavaScript 下载完毕后&#xff0c;相当于网站的页面…

技术流 | ClickHouse工具ckman v3.1.3 sinker v3.1.8 版本发布

【本文作者&#xff1a;擎创科技 ClickHouse专家&#xff0c;ckman作者禹鼎侯】 在这个端午小长假里&#xff0c;ckman和clickhouse_sinker分别带来了全新的版本。让我们一起来看看&#xff0c;新版本都有哪些新特性吧&#xff01; ckman v3.1.3新版本特性 ckman v3.1.3作为…

3D场景的交互设计有什么软件吗?

需求&#xff1a;类似于游戏那样在3D房间内&#xff0c;能通过鼠标或键盘操作在房间里自由行走。 对于3D场景的交互设计&#xff0c;尤其是像设计一间房间并允许用户在其中自由行走这样的需求&#xff0c;以下几款软件应该会适合&#xff1a; 1、博维数孪&#xff1a;专业从事…