我有两张桌子,[预订]和[食品价格].

表[保留]有两行:

    id  userId  foodId  date
     1     1      1     2023-02-08
     2     1      2     2023-03-14

[食品价格]表有四行:

id  foodId    date      price
 1     1    2023-01-24   25
 2     1    2023-03-05   30
 3     2    2023-01-24   25
 4     2    2023-03-05   30

我希望以这样的方式连接这两个表,使结果具有每个预订的最新价格.我写了这样一个查询:

SELECT [reservation].[id]
                    ,[reservation].[userId]
                    ,[reservation].[foodId]
                    ,[reservation].[date]
                    ,[food-prices].date
                    ,[food-prices].price
FROM [food].[dbo].[reservation]
LEFT OUTER JOIN [food-prices]
ON [reservation].foodId = [food-prices].foodId
AND [reservation].date >= [food-prices].date

它的结果是:

id  userId  foodId  [reservation].[date]    [food-prices].date    price
1      1       1         2023-02-08              2023-01-24        25
2      1       2         2023-03-14              2023-01-24        25
2      1       2         2023-03-14              2023-03-05        30

当我想要时

id  userId  foodId  [reservation].[date]    [food-prices].date    price
1      1       1         2023-02-08              2023-01-24        25
2      1       2         2023-03-14              2023-03-05        30

结果. 我应该如何写这样的查询呢?

推荐答案

您可以使用排名函数 for each foodid定义最新的行.然后连接数据.

CREATE TABLE reservation (
    id INT PRIMARY KEY,
    userId INT NOT NULL,
    foodId INT NOT NULL,
    date DATE NOT NULL
);

CREATE TABLE food_prices (
    id INT PRIMARY KEY,
    foodId INT NOT NULL,
    date DATE NOT NULL,
    price DECIMAL(10,2) NOT NULL
);

INSERT INTO reservation (id, userId, foodId, date)
VALUES (1, 1, 1, '2023-02-08'),
       (2, 1, 2, '2023-03-14');

INSERT INTO food_prices (id, foodId, date, price)
VALUES (1, 1, '2023-01-24', 25),
       (2, 1, '2023-03-05', 30),
       (3, 2, '2023-01-24', 25),
       (4, 2, '2023-03-05', 30);

SELECT *
FROM reservation R
INNER JOIN
(
    SELECT *
          ,ROW_NUMBER () OVER (PARTITION BY foodId ORDER BY date DESC) AS RowID
    FROM food_prices
) F
    ON R.foodId = F.foodId
WHERE F.RowID = 1;

enter image description here


那就试试这个吧:

SELECT *
FROM
(
    SELECT R.*
          ,f.date as food_price_date
          ,f.price
          ,ROW_NUMBER () OVER (PARTITION BY R.id ORDER BY F.date DESC) AS RowID
    FROM reservation R
    LEFT JOIN food_prices F
        ON R.foodId = F.foodId
        AND R.date >= F.date
) DS
WHERE RowID = 1

enter image description here

Sql相关问答推荐

如何转换和汇总行数

有没有一种正确的方法来利用SQL UNION来从三个潜在查询中 Select 最大值?

如何将资源密集型自连接转换为更快的查询?

如何优化我的功能以减少花费的时间?

根据Rails活动记录中时间戳/日期时间的时间部分从PostgreSQL中提取记录

无法将发票与产品价格相关联

从单个表达式中的分隔字符串中取平均值

提取连续时间戳范围的SQL

输出连续出现两次以上的行

仅当 SQL Server 中的表为开时,才在存储过程中使用更改跟踪

返回给定日期后的第 4 个工作日(不包括公众假期)

在SQL中实现表格数据透视类型报表

如何在sparksql查询中使用日期值?

如何根据共同列值从两个表中包含列,但只包含左表中的行

多行状态下的分组查询判断状态

使用 SAVE TRANSACTION 时 BEGIN 和 COMMIT 语句的数量不匹配

为每组填写行以进行旋转

如何通过存储过程将 root 的下一个子 node 作为父 node ?

Postgres 窗口函数未按预期工作

从多个连接返回 1 行到同一个表 - SQL Server