sql - 如何获取涉及三个SQL表的最旧数据
问题描述
我有三个表,Items,Orders和一个名为ItemOrders的多对多链接表。每个项目可以有很多订单,当然一个订单可以有很多项目。
我需要一个返回的项目列表:
- Items 表中的字段
- 订单表中的字段
但仅适用于每个项目的最早订单。我已经尝试了各种方式的连接和子查询,但就是无法理解如何做到这一点。
例如,项目:
+--------+---------------+
| ItemId | ItemName |
+--------+---------------+
| 1 | Crisps |
| 2 | Chocolate Bar |
+--------+---------------+
项目订单:
+--------+---------+
| ItemId | OrderId |
+--------+---------+
| 1 | 21 |
| 1 | 22 |
| 2 | 23 |
| 2 | 24 |
| 2 | 22 |
+--------+---------+
和订单:
+---------+------------+---------+
| OrderId | OrderDate | Name |
+---------+------------+---------+
| 21 | 2019-03-12 | ORD2501 |
| 22 | 2019-03-20 | ORD2502 |
| 23 | 2019-03-28 | ORD2503 |
| 24 | 2019-03-31 | ORD2504 |
+---------+------------+---------+
我试图得到这个:
+---------------+-----------+
| ItemName | OrderName |
+---------------+-----------+
| Crisps | ORD2501 |
| Chocolate Bar | ORD2502 |
+---------------+-----------+
任何有关正确方法的帮助将不胜感激。这适用于 MS SQL Server。
解决方案
一种方法是在其中CROSS APPLY
使用TOP (1)
and ORDER BY
:
SELECT I.itemName,
OD.OrderId
FROM dbo.Items I
CROSS APPLY (SELECT TOP (1) O.[Name]
FROM dbo.ItemOrders OI
JOIN dbo.Orders O ON OI.OrderID = O.OrderID
WHERE OI.ItemID = I.ItemID
ORDER BY O.OrderDate DESC) OD;
另一种方法是使用TOP (1) WITH TIES
and ROW_NUMBER
:
SELECT TOP (1) WITH TIES
I.ItemName,
O.[Name]
FROM dbo.Items I
JOIN dbo.ItemOrders OI ON OI.ItemID = I.ItemID
JOIN dbo.Orders O ON OI.OrderID = O.OrderID
ORDER BY ROW_NUMBER() OVER (PARTITION BY I.ItemID ORDER BY O.OrderDate DESC);
或者你可以放入ROW_NUMBER
一个 CTE,然后使用 aWHERE
来过滤:
WITH RN AS(
SELECT I.ItemName,
O.[Name],
ROW_NUMBER() OVER (PARTITION BY I.ItemID ORDER BY O.OrderDate DESC) AS RN
FROM dbo.Items I
JOIN dbo.ItemOrders OI ON OI.ItemID = I.ItemID
JOIN dbo.Orders O ON OI.OrderID = O.OrderID)
SELECT ItemName,
[Name]
FROM RNs
WHERE RN = 1;
推荐阅读
- reactjs - 直接在图像 uri 中传递 Aws url 函数会使图像在每次更新任何状态变量时都发生变化
- laravel - 在邮件视图中发送变量
- powershell - Set-SqlColumnEncryption 抛出错误
- laravel-4 - 在laravel 4.2中将一行上传到数据库表
- android - 无法模拟一个函数 mockito android
- java - 如何使用外部应用程序获取 Soap Web 服务的请求和响应详细信息?
- jquery - 如何将json文件上传到扩展?
- ssl - 如何为 tibjms 客户端强制执行 TLS1.2?
- android - Android Firebase,获取节点中键的位置
- authentication - 如何在没有 SSL 的情况下使用刷新令牌刷新谷歌访问令牌?