首页 > 解决方案 > 从它的事务中返回一个项目的持续时间,SQL

问题描述

(再次发帖,最后一个帖子不包括传出,被否决)

情况

有两个进站和一个出站。物品被扫描进出。我需要知道一件物品在车站里的时间。让我们将“站内”视为传入日期扫描和传出日期扫描之间的时间。

问题

  1. 一个项目可以(意外)多次扫描到任一站(为此,我正在考虑确定是否在同一天进行了扫描(而不是查看小时数),然后返回最早扫描的时间)

  2. 一个项目可以多次从工作站进出(多次进出扫描)

  3. 如果一个项目被扫描到两个传入位置,需要得到最早的时间

数据样本..

╔═════════╦════════╦══════════════════╦════════════════╦══════════╗
║ Row_num ║ ItemID ║      Dates       ║  LocationName  ║   Type   ║
╠═════════╬════════╬══════════════════╬════════════════╬══════════╣
║       1 ║ ItemA  ║ 1/7/20 12:49 PM  ║ Outgoing_Loc   ║ Outgoing ║
║       2 ║ ItemA  ║ 1/2/20 7:29 AM   ║ Incoming_Loc_A ║ Incoming ║
║       3 ║ ItemB  ║ 1/3/20 11:01 AM  ║ Outgoing_Loc   ║ Outgoing ║
║       4 ║ ItemB  ║ 1/2/20 4:57 PM   ║ Incoming_Loc_B ║ Incoming ║
║       5 ║ ItemB  ║ 1/2/20 5:01 PM   ║ Incoming_Loc_A ║ Incoming ║
║       6 ║ ItemB  ║ 12/12/19 5:58 PM ║ Outgoing_Loc   ║ Outgoing ║
║       7 ║ ItemB  ║ 12/12/19 5:57 PM ║ Outgoing_Loc   ║ Outgoing ║
║       8 ║ ItemB  ║ 5/20/19 10:19 AM ║ Outgoing_Loc   ║ Outgoing ║
║       9 ║ ItemC  ║ 1/9/20 9:20 AM   ║ Outgoing_Loc   ║ Outgoing ║
║      10 ║ ItemC  ║ 1/2/20 6:42 PM   ║ Incoming_Loc_A ║ Incoming ║
║      11 ║ ItemC  ║ 12/20/19 5:54 AM ║ Outgoing_Loc   ║ Outgoing ║
║      12 ║ ItemC  ║ 10/10/19 6:13 PM ║ Outgoing_Loc   ║ Outgoing ║
║      13 ║ ItemC  ║ 10/5/19 7:00 PM  ║ Incoming_Loc_A ║ Incoming ║
║      14 ║ ItemC  ║ 7/16/19 9:18 AM  ║ Outgoing_Loc   ║ Outgoing ║
╚═════════╩════════╩══════════════════╩════════════════╩══════════╝

我试图将每种类型的问题都提供到分配给不同项目的表格中。

完美的交易是ItemA,它是如此简单和干净,如果它们都是这样,那么我可以加入表格并将它们拉到单独的列上。

ItemB,你会注意到这个被扫描到两个传入的位置,但我只需要返回一个 - 它最早来自该批次。此外,需要返回最早传出(12/12/19)之后和最后传出(2020 年 1 月 3 日)之前的传入。

ItemC,类似于 ItemB 的最后一条语句,该项目两次从位置进出。需要获得按时间顺序最有意义的传入和传出对。

我不知道这有多难弄清楚,但我很难找到解决方案。我不确定如何在传出之间挤入传入日期。

输出示例:
需要获取每个项目在车站的天数。如果该项目已多次进出,则需要按时间顺序配对最有意义的传入和传出。例如,ItemC 有多个传入和传出日期,但我只需要具有开始和结束的日期作为一对。

+--------+-----------------+------------------+-----------------+
| ItemID |    Incoming     |     Outgoing     | Days in Station |
+--------+-----------------+------------------+-----------------+
| ItemA  | 1/2/20 7:29 AM  | 1/7/20 12:49 PM  | 5.00            |
| ItemB  | 1/2/20 4:57 PM  | 1/3/20 11:01 AM  | 1.00            |
| ItemC  | 1/2/20 6:42 PM  | 1/9/20 9:20 AM   | 7.00            |
| ItemC  | 10/5/19 7:00 PM | 10/10/19 6:13 PM | 5.00            |
+--------+-----------------+------------------+-----------------+

标签: sqlsql-serverjointransactionsmany-to-many

解决方案


如果不在查询中创建额外的表,我看不出如何做到这一点。

如果您不了解它们,这非常酷,并且会将您的 SQL 级别提升到一个新的级别。

IE

SELECT * 
FROM 
    (SELECT * FROM WHERE ...)

至少您需要以下表格: 显示项目是否已被多次扫描的表格。像这样订购该表

表 1A。物品; 传出次数;日期 按项目和日期顺序排序(将显示最早的日期)

表 1B 基于表 1A 取项目数超过一项的最早日期

表 2A。物品。传入的次数。按项目和日期顺序排序(将显示最早的日期)

表 2B 基于表 2A 取项目数超过一项的最早日期

使用表 1B 和 2B 得出你的答案。

其他人可能会更有耐心并给出更精致的答案,但希望以上有所帮助。


推荐阅读