【SQL边干边学系列】04中级问题(续)

文章目录

  • 前言
  • 回顾
  • 中级问题
    • 25.高昂运费
    • 26.2015年的高昂运费
    • 27.高昂运维 - 使用between
    • 28.去年的高昂运费
    • 29.库存清单
    • 30.没有任何订单的客户
    • 31.没有任何订单的客户,员工ID为4
  • 答案
    • 25.高昂运费
    • 26.2015年的高昂运费
    • 27.高昂运维 - 使用between
    • 28.去年的高昂运费
    • 29.库存清单
    • 30.没有任何订单的客户
    • 31.没有任何订单的客户,员工ID为4
  • 未完待续


前言

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

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

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

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

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


回顾

上篇文章👉《【SQL边干边学系列】03中级问题》 中讨论了部分中级问题,这篇文章我们接着讨论剩余的中级问题。


中级问题

25.高昂运费

运往某些国家的运费很高。我们希望为客户提供更多的选择,以便降低他们的运费。返回总体平均运费最高的三个国家,按平均运费降序排列。

-- 预期结果
ShipCountry      AverageFreight
--------------- ---------------------
Austria         184.7875
Ireland         145.0126
USA             112.8794
(3 row(s) affected)

提示如下

我们将使用订单表(Orders),并使用货运(Freight)和运往国家( ShipCountry)字段。

你需要按ShipCountry进行分组,并使用Avg函数,使用如下的语句:

Select ShipCountry,AverageFreight = avg(freight)
From Orders
Group By ShipCountry
Order By AverageFreight desc;

现在你只需要显示前3行。

26.2015年的高昂运费

我们将继续讨论上述关于高昂运费的问题。现在,我们只想看到2015年的订单。

-- 预期结果
ShipCountry     AverageFreight
--------------- ---------------------
Austria         178.3642
Switzerland     117.1775
France          113.991
(3 row(s) affected)

提示如下:

你需要在上一个问题的查询中添加一个Where子句,过滤OrderDate字段。

在筛选日期时,你需要知道OrderDate字段是DateTime还是Date。

27.高昂运维 - 使用between

对上述问题的另一个(不正确的)答案是:

Select Top 3ShipCountry,AverageFreight = avg(freight)
From Orders
WhereOrderDate between '1/1/2015' and '12/31/2015'
Group By ShipCountry
Order By AverageFreight desc;

注意,当你运行这个语句时,它将返回错误的结果。

上面的(错误的)答案缺失的订单ID是什么?为什么不显示2015年12月31日的订单呢?

运行此查询,并查看2015年12月31日左右的行。你注意到了什么?特别看一下Freight字段。

select * from orders order by OrderDate

28.去年的高昂运费

我们继续处理高昂运费的问题。我们现在希望得到平均运费最高的三个国家。但是,我们不希望对特定年份进行筛选,而是使用最后12个月的订单数据,使用订单表(Orders)中订单日期(OrderDate)的最后一个作为结束日期。

-- 预期结果
ShipCountry     AverageFreight
--------------- ---------------------
Ireland         200.21
Austria         186.4596
USA             119.3032
(3 row(s) affected)

提示如下

首先,获取Orders中的最后一个OrderDate。你应该使用这样的语句:Select Max(OrderDate) from Orders

现在你需要计算从最后一个OrderDate往前数1年的日期。你应该使用这样的语句:Select Dateadd(yy, -1, (Select Max(OrderDate) from Orders))。现在你只需要把它放在where子句中。

29.库存清单

我们正在做库存,按照以下格式显示所有订单的信息。按订OrderID和Product ID排序。

-- 预期结果
EmployeeID  LastName     OrderID     ProductName                        Quantity
----------- ------------ ----------- ---------------------------------- --------
5           Buchanan     10248       Queso Cabrales                     12
5           Buchanan     10248       Singaporean Hokkien Fried Mee      10
5           Buchanan     10248       Mozzarella di Giovanni             5
6           Suyama       10249       Tofu                               9
6           Suyama       10249       Manjimup Dried Apples              40
4           Peacock      10250       Jack's New England Clam Chowder    10
4           Peacock      10250       Manjimup Dried Apples              35

(total 2155 rows)

提示 :你需要连接4个表,并且只显示那些必要的字段。

30.没有任何订单的客户

有些客户从未真正下过订单。显示这些客户。

-- 预期结果
Customers_CustomerID Orders_CustomerID
-------------------- -----------------
FISSA                NULL
PARIS                NULL
(2 row(s) affected)

提示如下

其中一种方法是使用左连接,也被称为左外连接。

SelectCustomers_CustomerID = Customers.CustomerID ,Orders_CustomerID = Orders.CustomerID
From Customers left join Orderson Orders.CustomerID = Customers.CustomerID

这是一个很好的开始。它显示了“Customers”表中的所有记录,以及“Orders”表中的匹配记录。但是,我们只希望那些在Orders表中 CustomerID 为null的记录,需要使用过滤器实现。

31.没有任何订单的客户,员工ID为4

一名员工(员工编号EmployeeID为4)下的订单最多。然而,也有一些顾客从未向她下过订单。只展示那些从未向她下过订单的顾客。

-- 预期结果
CustomerID CustomerID
---------- ----------
SEVES      NULL
THEBI      NULL
LAZYK      NULL
GROSR      NULL
PARIS      NULL
FISSA      NULL
SPECD      NULL
LAUGB      NULL
PRINI      NULL
VINET      NULL
FRANR      NULL
CONSH      NULL
NORTS      NULL
PERIC      NULL
DUMON      NULL
SANTG      NULL
(16 row(s) affected)

提示如下

基于之前的问题,你可能会认为应该这样做:

SelectCustomers.CustomerID ,Orders.CustomerID
From Customers left join Orderson Orders.CustomerID = Customers.CustomerID
WhereOrders.CustomerID is nulland Orders.EmployeeID = 4

但是,这样不会返回任何结果。

请注意,对于外部连接,where子句上的过滤器将作用与连接之后。


答案

25.高昂运费

答案

Select Top 3ShipCountry,AverageFreight = Avg(freight)
From Orders
Group By ShipCountry
Order By AverageFreight desc;

讨论

只显示一定数量的记录的最简单和最常用的方法是使用Top。另一种方法是使用偏移量,如下所示。

SelectShipCountry,AverageFreight = AVG(freight)
From Orders
Group By ShipCountry
Order by AverageFreight DESC
OFFSET 0 ROWS FETCH FIRST 3 ROWS ONLY

26.2015年的高昂运费

答案

Select Top 3ShipCountry,AverageFreight = avg(freight)
From Orders
WhereOrderDate >= '20150101'and OrderDate < '20160101'
Group By ShipCountry
Order By AverageFreight desc;

讨论

写where子句的另一种方法是:

WhereOrderDate >= '1/1/2015'and OrderDate < '1/1/2016'

这里还有另一种方式:

Select Top 3ShipCountry,AverageFreight = avg(freight)
From Orders
Whereyear(OrderDate) = 2015 -- 使用Year函数
Group By ShipCountry
Order By AverageFreight desc;

27.高昂运维 - 使用between

答案

导致不同结果的OrderID是10806。

讨论

如果OrderDate是一个Date,而不是DateTime,那么这个SQL就可以正常工作。

OrderDate between '1/1/2015' and '12/31/2015'

然而,由于它是一个DateTime字段,它给出了一个错误的答案,因为它没有考虑到OrderDate在2015年12月31日当天的记录。

请注意,对于DateTime字段,12/31/2015 等价于2015-12-31 00:00:00.000

28.去年的高昂运费

答案

Select TOP (3)ShipCountry,AverageFreight = Avg(freight)
From Orders
WhereOrderDate >= Dateadd(yy, -1, (Select max(OrderDate) from Orders))
Group by ShipCountry
Order by AverageFreight desc;

讨论

使用这样的SQL可以生成动态日期范围,这对于大多数数据分析工作是至关重要的。大多数报告和查询都需要是灵活的,没有硬编码日期值的方式。

29.库存清单

答案

SelectEmployees.EmployeeID,Employees.LastName,Orders.OrderID,Products.ProductName,OrderDetails.Quantity
From Employeesjoin Orderson Orders.EmployeeID = Employees.EmployeeIDjoin OrderDetailson Orders.OrderID = OrderDetails.OrderIDjoin Productson Products.ProductID = OrderDetails.ProductID
Order byOrders.OrderID,Products.ProductID

讨论

这个问题更多的是使用多个表的Join。你可以用 Inner Join来替换Join,但大多数人只是使用Join。

30.没有任何订单的客户

答案

SelectCustomers_CustomerID = Customers.CustomerID ,Orders_CustomerID = Orders.CustomerID
From Customers left join Orderson Orders.CustomerID = Customers.CustomerID
WhereOrders.CustomerID is null

讨论

有很多方法可以得到相同的结果。

在上面,我们使用了Left Join。当性能相等时,我更喜欢Not In方法,如下所示。

Select CustomerID 
From Customers 
WhereCustomerID not in (select CustomerID from Orders)

另一个选择是使用Not Exists。这需要一个相关子查询。

Select CustomerID 
From Customers 
Where Not Exists(Select CustomerID from Orders whereOrders.CustomerID = Customers.CustomerID)

31.没有任何订单的客户,员工ID为4

答案

SelectCustomers.CustomerID ,Orders.CustomerID
From Customers left join Orderson Orders.CustomerID = Customers.CustomerIDand Orders.EmployeeID = 4
WhereOrders.CustomerID is null

讨论

因为Where子句中的过滤器是应用在连接之后的结果上,所以我们需要在连接子句中EmployeeID = 4过滤器,而不是在Where子句中。

运行下面的查询并查看结果。它应该能让你更好地了解“is null”是如何工作的。请注意,Where子句已经被注释掉了。

SelectCustomers.CustomerID ,Orders.CustomerID,Orders.EmployeeID
From Customers left join Orderson Orders.CustomerID = Customers.CustomerIDand Orders.EmployeeID = 4
-- Where 
-- Orders.CustomerID is null

解决这类问题最常见的方法是使用左连接。然而,下面是另一种替代方案。

--  Not In 方案
Select CustomerID 
From Customers 
WhereCustomerID not in (select CustomerID from Orders where EmployeeID = 4)
--  Not Exists 方案
Select CustomerID 
From Customers 
Where Not Exists(Select CustomerID from Orders where Orders.CustomerID = Customers.CustomerID and EmployeeID = 4)

未完待续

中级问题到此结束。下一篇开始讨论高级问题。


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

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

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

相关文章

CVE-2022-4230

CVE-2022-4230 漏洞介绍 WP Statistics WordPress 插件13.2.9之前的版本不会转义参数&#xff0c;这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下&#xff0c;具有管理选项功能 (admin) 的用户可以使用受影响的功能&#xff0c;但是该插件有一个设置允许低权限用…

DDMA信号处理以及数据处理的流程---DDMA原理介绍

Hello&#xff0c;大家好&#xff0c;我是Xiaojie&#xff0c;好久不见&#xff0c;欢迎大家能够和Xiaojie一起学习毫米波雷达知识&#xff0c;Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程&#xff0c;本系列文章将从目标生成、信号仿真、测距、测速、cfar…

vscode设置代码自动换行显示

☆ 问题描述 vscode设置代码自动换行显示 ★ 解决方案 ✅ 总结

每日两题 / 198. 打家劫舍 74. 搜索二维矩阵(LeetCode热题100)

198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; dp[i]表示考虑前i 1号房屋&#xff0c;能获取的最大金额。对于没一间房屋都有偷与不偷两种选择 如果偷&#xff0c;需要从dp[i - 2]转移&#xff0c;因为不能偷窃相邻房屋&#xff0c;dp[i] dp[i - 2] nums[i] 如果…

稍微学学react

文章开始前&#xff0c;先划划水~ 今日份开心&#xff1a; 今天看之前发布的按钮npm包下载量有162次&#xff0c;早知道好好做了 今日份不开心&#xff1a; 爬岗位看到一个整体都挺满意的岗位&#xff0c;公司位置和发展大方向都好喜欢&#xff01;&#xff01;&#xff01;…

【PL理论】(6) F#:标准库之列表(List)

​​​​​ &#x1f4ad; 写在前面&#xff1a;本章我们将介绍 F# 标准库的列表&#xff0c;我们将简单的先过一遍列表的一些常用操作&#xff0c;具体的讲解我们将放在后续章节。 目录 0x00 标准库&#xff1a;列表&#xff08;List&#xff09; 0x01 模式匹配与列表 0x…

14.8k Star!CrewAI:部署一支由你指挥的人工智能代理大军,股票分析、发布帖子、支持Ollama!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 14.8k Star&#xff01;CrewAI&#xff1a;部署一支由你指挥的人工智能代理大军&#xff0c;股票分析、发布帖子、支持Ollama&#xff01;…

计算机组成结构—多处理器

目录 一、SISD、SIMD、MIMD 和向量处理器 1. 费林分类法 2. SIMD 和向量处理器 二、硬件多线程 三、多核处理器和 SMP 1. 多核处理器 2. 共享内存多处理器&#xff08;SMP&#xff09; 3. MPP 和集群 一、SISD、SIMD、MIMD 和向量处理器 通过改进系统结构&#xff0c;可…

C++设计模式-外观模式,游戏引擎管理多个子系统,反汇编

运行在VS2022&#xff0c;x86&#xff0c;Debug下。 30. 外观模式 为子系统定义一组统一的接口&#xff0c;这个高级接口会让子系统更容易被使用。应用&#xff1a;如在游戏开发中&#xff0c;游戏引擎包含多个子系统&#xff0c;如物理、渲染、粒子、UI、音频等。可以使用外观…

图像算法---自动曝光AE

一&#xff0c;自动曝光AE 自动曝光&#xff08;AE&#xff0c;全称Auto Exposure&#xff09;是一种在摄影和摄像中广泛使用的技术&#xff0c;它允许相机或摄像机根据环境光线条件自动调整曝光参数&#xff0c;以获得清晰、亮度适中的图像或视频。以下是关于自动曝光AE的详细…

31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络

前面两篇文章我们分析了HTTP/1和HTTP/2&#xff0c;在HTTP/2出现之前&#xff0c;开发者需要采取很多变通的方式来解决HTTP/1所存在的问题&#xff0c;不过HTTP/2在2018年就开始得到了大规模的应用&#xff0c;HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…

优卡集团冲刺港股上市:90后创始团队孵化,IPO前突击大额分红

现年26岁的鲁圳&#xff0c;正在带领其6年以来的创业成果冲击资本市场。 近日&#xff0c;金融居间机构服务商优卡集团&#xff08;Yoc Group&#xff09;向港交所递交上市申请&#xff0c;民银资本为其独家保荐人。透过招股书可知&#xff0c;优卡集团成立于2018年&#xff0…

【CTF-Web】文件上传漏洞学习笔记(ctfshow题目)

文件上传 文章目录 文件上传What is Upload-File&#xff1f;Upload-File In CTFWeb151考点&#xff1a;前端校验解题&#xff1a; Web152考点&#xff1a;后端校验要严密解题&#xff1a; Web153考点&#xff1a;后端校验 配置文件介绍解题&#xff1a; Web154考点&#xff1a…

vcruntime140.dll找不到的正确处理方法,vcruntime140.dll是什么文件

vcruntime140.dll找不到的这个问题&#xff0c;相信不少人都有遇到吧&#xff1f;其实遇到了也不需要害怕&#xff0c;这只是一个很小的问题&#xff0c;我们完全可以自己快速修复。还有就是缺失这个vcruntime140.dll文件&#xff0c;你的一些程序是会打不开的&#xff0c;不用…

揭秘!2024版Camtasia永久免费,全新功能体验

在当今数字时代&#xff0c;视频已经成为了我们生活中不可或缺的一部分。无论是在工作中进行演示、培训&#xff0c;还是在生活中分享生活点滴&#xff0c;视频都扮演着重要的角色。而要想制作出高质量的视频&#xff0c;一款专业的录屏软件是必不可少的。今天&#xff0c;我就…

PHP函数大全之array_count_values()

array_count_values()函数是用于计算数组中每个值的出现次数的PHP函数&#xff0c;并返回一个关联数组&#xff0c;该数组的键表示原始数组中的唯一值&#xff0c;而键值表示该值在原始数组中的出现次数。 array_count_values()函数的一些注意事项&#xff1a; 该函数不区分大…

美团发布2024年一季度财报:营收733亿元,同比增长25%

6月6日&#xff0c;美团(股票代码:3690.HK)发布2024年第一季度业绩报告。受益于经济持续回暖和消费复苏&#xff0c;公司各项业务继续取得稳健增长&#xff0c;营收733亿元(人民币&#xff0c;下同)&#xff0c;同比增长25%。 财报显示&#xff0c;一季度&#xff0c;美团继续…

Linux应用 sqlite3编程

1、概念 SQLite3是一个轻量级的、自包含的、基于文件的数据库管理系统&#xff0c;常用于移动设备、嵌入式设备和小型应用程序中&#xff0c;应用场景如下&#xff1a; 移动应用程序&#xff1a;由于SQLite3是零配置、无服务器的数据库引擎&#xff0c;非常适合用于移动应用程…

uni微信小程序editor富文本组件如何插入图片

需求 在editor中插入图片&#xff0c;并对图片进行编辑&#xff0c;简略看一下组件的属性&#xff0c;官网editor 组件 | uni-app官网 解决方案 首先要使用到ready这个属性&#xff0c;然后官网有给代码粘过来&#xff0c;简单解释一下这段代码的意思&#xff08;作用是在不同…

星火秘境游戏开发链游app定制开发源码部署

星火秘境是一款神秘而充满冒险的游戏&#xff0c;开发这样一款游戏需要综合考虑多个方面&#xff0c;包括游戏设计、美术设计、程序开发、音效制作等。下面我将简要介绍一下游戏开发和链游app搭建的一般流程&#xff1a; 游戏设计&#xff1a; 确定游戏类型&#xff1a;星火秘…