当前位置: 首页 > news >正文

从一题了解 CROSS JOIN 与 DATEDIFF:SQL 天气温度对比实战

在 SQL 学习中,JOIN 子查询和日期函数是高频考点,也是实际业务中常用的组合技能。今天我们就通过一道经典的天气温度对比题,吃透 CROSS JOIN(交叉连接)和 DATEDIFF 函数的用法,同时理解“自连接”的核心逻辑。

一、题目背景与需求

题目描述

现有一张天气表 Weather,结构如下:

列名类型说明
idint唯一标识(主键)
recordDatedate记录日期
Temperatureint当日温度

要求查询出 所有温度比前一天高的日期对应的 id

示例输入输出

假设表中数据如下:

idrecordDateTemperature
12023-01-0110
22023-01-0220
32023-01-0315
42023-01-0425

期望输出:

id
2
4

解释:2023-01-02(20℃)比前一天(10℃)高,2023-01-04(25℃)比前一天(15℃)高,因此返回对应的 id 2 和 4。

二、核心知识点拆解

要解决这道题,需要掌握两个关键技能:CROSS JOIN 自连接 和 DATEDIFF 日期差计算。

1. 先搞懂:为什么要用 CROSS JOIN 自连接?

我们的需求是“对比当日与前一天的温度”,本质是 将表中的每条记录与它的“前一天记录”进行配对

  • 普通查询只能获取单条记录的信息,无法直接关联两条不同日期的记录;
  • 自连接(将表与自身连接)是实现“同表不同行对比”的核心方法;
  • CROSS JOIN 是交叉连接,会返回两张表所有记录的笛卡尔积(即表 A 每条记录与表 B 每条记录配对)。但我们通过 ON 条件筛选后,就能精准得到“当日-前一天”的配对组合。

这里的关键逻辑:

  • Weather 表看成两张表:A 表(代表“当日”)和 B 表(代表“前一天”);
  • 我们需要 A 表的日期 = B 表的日期 + 1 天,这样就实现了“当日与前一天”的配对。

2. 再吃透:DATEDIFF 函数的用法

DATEDIFF 是 SQL 中用于计算两个日期之间差值的函数,语法因数据库(MySQL、SQL Server、Oracle)略有差异,但核心逻辑一致:

通用语法(以 MySQL 为例)
DATEDIFF(date1, date2)
  • 功能:计算 date1 减去 date2 的天数差;
  • 返回值:整数(正数表示 date1 晚于 date2,负数表示 date1 早于 date2,0 表示日期相同)。
本题中的应用

我们需要“A 表日期比 B 表日期晚 1 天”,因此条件为:

DATEDIFF(a.recordDate, b.recordDate) = 1
  • a.recordDate 是 2023-01-02,b.recordDate 是 2023-01-01,差值为 1,符合条件;
  • 其他配对(如差值为 2、-1)都会被过滤掉。
不同数据库的兼容说明
  • SQL Server:DATEDIFF(day, b.recordDate, a.recordDate) = 1(需要指定日期部分);
  • Oracle:没有 DATEDIFF,需用 a.recordDate - b.recordDate = 1(Oracle 中日期直接相减得到天数差)。

三、完整解题步骤

步骤 1:使用 CROSS JOIN 自连接表

Weather 表自连接,分别命名为 a(当日)和 b(前一天):

SELECT a.id
FROM Weather AS a
CROSS JOIN Weather AS b

此时会生成笛卡尔积(比如 4 条记录的表会生成 4×4=16 条配对),大部分配对是无效的,需要筛选。

步骤 2:用 DATEDIFF 筛选“当日-前一天”配对

通过 ON 条件保留“a 的日期比 b 晚 1 天”的配对:

SELECT a.id
FROM Weather AS a
CROSS JOIN Weather AS b
ON DATEDIFF(a.recordDate, b.recordDate) = 1

此时配对结果已精准过滤,只保留“当日与前一天”的组合(如 (2,1)、(3,2)、(4,3))。

步骤 3:筛选温度更高的记录

添加 WHERE 条件,要求当日温度(a.Temperature)高于前一天温度(b.Temperature):

SELECT a.id
FROM Weather AS a
CROSS JOIN Weather AS b
ON DATEDIFF(a.recordDate, b.recordDate) = 1
WHERE a.Temperature > b.Temperature;

最终结果验证

代入示例数据,筛选后的有效配对为:

  • (a.id=2, b.id=1):20℃ > 10℃ → 保留;
  • (a.id=3, b.id=2):15℃ < 20℃ → 排除;
  • (a.id=4, b.id=3):25℃ > 15℃ → 保留;

最终输出 id=2 和 4,与期望结果一致。

四、常见误区与优化

误区 1:混淆 DATEDIFF 的参数顺序

错误写法:DATEDIFF(b.recordDate, a.recordDate) = 1
此时要求 b 的日期比 a 晚 1 天(即 a 是前一天,b 是当日),与需求相反,会导致无结果或错误结果。

误区 2:忘记自连接的表别名

如果不使用 AS aAS b,SQL 会无法区分两个表的同名字段(如 recordDate),直接报错。

优化:用 INNER JOIN 替代 CROSS JOIN

CROSS JOIN + ON 本质上等同于 INNER JOIN(内连接),因为 ON 条件会过滤掉无效配对。因此也可以写成更简洁的内连接形式(语义更清晰):

SELECT a.id
FROM Weather AS a
INNER JOIN Weather AS b
ON DATEDIFF(a.recordDate, b.recordDate) = 1
WHERE a.Temperature > b.Temperature;

两种写法结果完全一致,INNER JOIN 更符合“筛选有效连接”的语义,推荐日常使用。

五、总结

通过这道题,我们不仅学会了具体的解题方法,更理解了背后的核心逻辑:

  1. 同表不同行对比 → 用自连接(将表视为两张独立表);
  2. 日期差值计算 → 用DATEDIFF(根据数据库选择对应语法);
  3. CROSS JOIN + ON 等同于 INNER JOIN,核心是通过条件筛选有效配对。

这类“对比相邻记录”的场景在实际业务中非常常见(如环比增长、连续登录判断等),掌握自连接和日期函数的组合用法,能轻松应对这类问题。建议大家多尝试修改条件(如查询温度比后一天高的记录、计算连续 2 天升温的 id),加深对知识点的理解~

http://www.dtcms.com/a/574001.html

相关文章:

  • js:requestAnimationFrame的使用
  • 【JUnit实战3_29】第十八章:REST API 接口测试(上)——RESTful 风格的后端 API 的搭建
  • 回调函数的作用与举例(Python版)
  • 克旗网站制作5229998建设银行网站会员
  • 洛阳市政建设网站网站建设中 html免费
  • 自己创建网站怎么赚钱青海省住房建设厅网站首页
  • MiniEngine学习笔记 : DescriptorHeap
  • 智能合约与智能合约开发交互详解
  • 我想出租做房 请问哪个网站好些泰安最新通告今天
  • 下一代CDN安全体系:融合加速、抗攻击与业务智能
  • 光纤传输器与网络延长器2合1技术解析:
  • OpenHarmony开发实践-鸿蒙napi开发实践
  • Redis识别缓存与数据库数据的不一致性以及识别热Key教程
  • 网站运营培训机构网站建设是做什么的
  • 商丘网站建设专业现状网站首页布局
  • 28.DHCP
  • Linux基础指令-Linux学习笔记(1)
  • 可以推广网站市网站制作
  • STM32TIM定时器PWM1模式与PWM2模式配置
  • 阿勒泰建设局网站北京模板网站建设费用
  • 上传OSS直传
  • 网站正在建设中页面 英文翻译网络网站建设电话
  • 外企渣打内推
  • TGRS 即插即用 | 超越传统U-Net!ASCNet融合小波变换与全局注意力,重新定义图像修复范式
  • 一线城市网站建设费用高wordpress调用id数据
  • BOD5快速测定仪:环境水质监测的高效解决方案
  • 【仓颉纪元】仓颉性能优化深度实战:5 天让应用提速 300%
  • 全网营销型网站建设公司wordpress 个人soho
  • Python 正则表达式实战 + 详解:从匹配QQ邮箱到掌握核心语法
  • 五度易链产业大脑技术拆解:AI + 大数据 + 云计算如何构建产业链数字基础设施?