如何获取涉及三个SQL表的最旧数据

如何获取涉及三个SQL表的最旧数据,sql,sql-server,Sql,Sql Server,我有三个表,Items,Orders和一个名为ItemOrders的多对多链接表。 每个项目可以有许多订单,当然,一个订单可以有许多项目 我需要返回的项目列表: Items表中的字段 Orders表中的字段 但仅适用于每个项目的最旧订单。我已经尝试过各种连接和子查询,但就是不知道该怎么做 例如,项目: 项目订单: 及命令: 我正试图得到这个: +---------------+-----------+ | ItemName | OrderName | +---------------+

我有三个表,Items,Orders和一个名为ItemOrders的多对多链接表。 每个项目可以有许多订单,当然,一个订单可以有许多项目

我需要返回的项目列表:

Items表中的字段 Orders表中的字段 但仅适用于每个项目的最旧订单。我已经尝试过各种连接和子查询,但就是不知道该怎么做

例如,项目:

项目订单:

及命令:

我正试图得到这个:

+---------------+-----------+
|   ItemName    | OrderName |
+---------------+-----------+
| Crisps        | ORD2501   |
| Chocolate Bar | ORD2502   |
+---------------+-----------+

如果您能提供正确方法方面的任何帮助,我们将不胜感激。这适用于MS SQL Server。

一种方法是横向联接:

select i.*, o.orderid
from items i outer apply
     (select top (1) o.*
      from itemOrders io join
           Orders o
           on io.orderid = o.orderid
      where io.itemid = i.itemid
      order by o.orderdate desc
     ) o
一种方法是使用带TOP 1和ORDER BY的交叉应用:

选择I.itemName, OD.OrderId 来自dbo.Items I 交叉应用选择前1位[名称] 来自dbo.ItemOrders OI 在OI.OrderID=O.OrderID上加入dbo.Orders 其中OI.ItemID=I.ItemID 按O.ORDERDDATE DESC OD订购; 另一种方法是使用带有领带和行号的TOP 1:

选择带领带的前1名 一、项目名称, O.[姓名] 来自dbo.Items I 在OI.ItemID=I.ItemID上加入dbo.ItemOrders OI 在OI.OrderID=O.OrderID上加入dbo.Orders 按I.ItemID按分区按行编号排序按O.OrderDate DESC排序; 或者,您可以将行号放入CTE,然后使用WHERE to filter:

以注册护士为例 选择I.ItemName, O.[姓名], 按I.ItemID按O.OrderDate DESC按RN排序的分区上的行数 来自dbo.Items I 在OI.ItemID=I.ItemID上加入dbo.ItemOrders OI 在OI.OrderID=O.OrderID上加入dbo.Orders 选择ItemName, [姓名] 来自RNs 其中RN=1;
尝试使用按医嘱排序的行号。注意,表有列,而不是字段。在SQL世界中。这很有效,谢谢。但是它运行得很慢。另一个答案中的CTE运行得非常快。@FeridunKadir。比这快?这让我有点吃惊。是否在所有表上都声明了主键?
+---------+------------+---------+
| 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   |
+---------------+-----------+
select i.*, o.orderid
from items i outer apply
     (select top (1) o.*
      from itemOrders io join
           Orders o
           on io.orderid = o.orderid
      where io.itemid = i.itemid
      order by o.orderdate desc
     ) o