SQL查询特定时间段内最大可用商品数(预订系统)

标签 sql sql-server oracle

对于预订系统,有一个库存表,每个项目都有一个数量(例如,有 20 张椅子)。现在,用户可以预订特定时间段(例如,两小时 5 张椅子“2010-11-23 15:00”-“2010-11-23 17:00”;另一次预订可以持续几天“2010-11-24 11:00”-“2010-11-26 14:00”)。

检查在请求的时间段内仍有多少商品可用的最佳方法是什么?

用户应该输入他想要预订的时间(从,到),并且他应该看到在此期间仍有多少库存商品。

table "inventory"
-------------------
inventory_id (int) 
quantity (int)

table "reservation"
-------------------
reservation_id (int)
inventory_id (int)
quantity (int)
from (datetime)
until (datetime)

预留可以重叠,但对于某个时间点,仅应预留库存.数量 项。

简单示例:

我们有 40 张椅子。

存在以下保留:

R1 2010-11-23 14:00 - 2010-11-23 15:30 -> 5 chairs reserved
R2 2010-11-23 15:00 - 2010-11-23 16:00 -> 10 chairs reserved
R3 2010-11-23 17:00 - 2010-11-23 17:30 -> 20 chairs reserved

用户提出多个预订请求(查询):

Q1 2010-11-23 15:00 - 2010-11-23 17:00 -> 25 chairs are available
Q2 2010-11-23 15:45 - 2010-11-23 17:00 -> 30 chairs are available
Q3 2010-11-23 16:30 - 2010-11-23 18:00 -> 30 chairs are available
Q4 2010-11-23 15:10 - 2010-11-23 15:20 -> 25 chairs are available
Q5 2010-11-23 13:30 - 2010-11-23 17:30 -> 20 chairs are available

如何查询请求期间的最大可用数量?或者是否需要不同的 table 设计?目标数据库系统是Oracle和SQL-Server。

更新:

我尝试在不更改原始示例的情况下“可视化”保留 R1 和 R2 以及查询 Q1 - Q5。我添加了 Q4 和 Q5 作为附加示例。 av 显示可用数量。

       R1  R2  R3  av
13:30              40                  Q5
14:00   5          35                  Q5
14:30   5          35                  Q5
15:00   5  10      25  Q1              Q5
15:10   5  10      25  Q1          Q4  Q5
15:20   5  10      25  Q1              Q5
15:30      10      30  Q1              Q5
15:45      10      30  Q1  Q2          Q5
16:00              40  Q1  Q2          Q5
16:30              40  Q1  Q2  Q3      Q5
17:00          20  20          Q3      Q5
av                     25  30  20  25  20

最佳答案

你可以尝试这样的事情(完整的工作示例)

DECLARE @inventory TABLE(
    inventory_id int, 
    quantity int
)

DECLARE @reservation TABLE(
    reservation_id int,
    inventory_id int,
    quantity int,
    [from] datetime,
    until datetime
)

INSERT INTO @inventory SELECT 1, 40

INSERT INTO @reservation SELECT 1, 1, 5, '2010-11-23 14:00 ', '2010-11-23 15:30'
INSERT INTO @reservation SELECT 1, 1, 10, '2010-11-23 15:00 ', '2010-11-23 16:00'

DECLARE @Start DATETIME,
        @End DATETIME

SELECT  @Start = '2010-11-23 15:00',
        @End = '2010-11-23 17:00'

SELECT  TotalUsed.inventory_id,
        i.quantity - ISNULL(TotalUsed.TotalUsed,0) Available
FROM    @inventory i LEFT JOIN
        (
            SELECT  inventory_id,
                    SUM(quantity) TotalUsed
            FROM    @reservation
            WHERE   [from] BETWEEN @Start AND @End
            OR      until BETWEEN @Start AND @End
            GROUP BY inventory_id
        ) TotalUsed ON  TotalUsed.inventory_id = i.inventory_id


SELECT  @Start = '2010-11-23 15:45',
        @End = '2010-11-23 17:00'

SELECT  TotalUsed.inventory_id,
        i.quantity - ISNULL(TotalUsed.TotalUsed,0) Available
FROM    @inventory i LEFT JOIN
        (
            SELECT  inventory_id,
                    SUM(quantity) TotalUsed
            FROM    @reservation
            WHERE   [from] BETWEEN @Start AND @End
            OR      until BETWEEN @Start AND @End
            GROUP BY inventory_id
        ) TotalUsed ON  TotalUsed.inventory_id = i.inventory_id

结果

inventory_id Available
------------ -----------
1            25


inventory_id Available
------------ -----------
1            30

关于SQL查询特定时间段内最大可用商品数(预订系统),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3433727/

相关文章:

sql-server - 如何将 SQL 数据库中的字段从 numeric(18) 更改为 varchar(10)

oracle - 如何更改 Oracle 日期变量中存储的小时值?

mysql - 加入结果并进行算术平均

sql - 如何在 SQL Server 中进行批量更新

java - 在登录期间选择命令有什么更好的方法吗?

c# - 如何删除表中的这种冗余?

c# - System.Data.SqlClient.SqlException 与网络相关或特定于实例的错误

c# - Linq DELETE 在 SQL Server 中生成 UPDATE 查询

database - 从 Windows 7 64 位连接到 32 位 Oracle 数据库

oracle - ORA-01882:在Liquibase Gradle插件中找不到时区区域