如何根据具有最后时间戳的行筛选 SQL 结果?
How Can I Filter SQL Results Based On Row With Last Timestamp?
我是 SQL 的新手;请原谅这个问题的幼稚
假设您有一个 table,其中每一行都有以下条目,所有条目都是 varchar(50):DocumentName、DocumentNumber、Status、PreviousUser、NextUser、Timestamp。时间戳使得字母排序也是按时间顺序排列的。虽然每一行都是唯一的,但不能保证每一行的 DocumentName 和 DocumentNumber 条目都是唯一的。
我想对 returns unique DocumentName、DocumentNumber 和 Status last 该 DocumentName 和 DocumentNumber 的 NextUser 条目(按时间戳测量)与我拥有的字符串匹配。我如何将其格式化为查询?
这是一个示例 table,其中包含示例 returns,可能有助于阐明我的要求。
+================+================+============+==============+==========+============+
| DocumentName | DocumentNumber | Status | PreviousUser | NextUser | Timestamp |
+================+================+============+==============+==========+============+
| Change Request | 1 | PROCESSING | SSMITH | MJONES | 2020 02 01 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 1 | DRAFT | JDOE | SSMITH | 2020 01 01 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 1 | COMPLETE | SSMITH | NULL | 2020 02 22 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 1 | APPROVAL | MJONES | SSMITH | 2020 02 21 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 3 | PROCESSING | JDOE | SSMITH | 2020 04 17 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 1 | APPROVAL | SSMITH | MJONES | 2020 01 01 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 1 | REWORK | MJONES | SSMITH | 2020 03 03 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 1 | APPROVAL | SSMITH | MJONES | 2020 03 07 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 7 | DRAFT | JDOE | SSMITH | 2020 03 17 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 7 | APPROVAL | SSMITH | MJONES | 2020 03 19 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 1 | PROCESSING | JDOE | SSMITH | 2020 05 03 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 1 | DRAFT | JDOE | JDOE | 2020 05 02 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 9 | COMPLETE | JDOE | NULL | 2020 06 24 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 13 | DRAFT | JDOE | SSMITH | 2020 07 04 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 13 | REWORK | SSMITH | JDOE | 2020 07 17 |
+----------------+----------------+------------+--------------+----------+------------+
如果我想匹配JDOE,我应该返回一行:('Problem Report', 13).
如果我想匹配 SSMITH,我应该返回两行:('Change Request', 3) 和 ('Problem Report', 1).
如果我想匹配 MJONES,我应该返回两行:('User Request', 1) 和 ('User Request', 7).
如果我有什么不明确的地方,请告诉我。
这有帮助吗?
Select DISTINCT DocumentName, DocumentNumber, Status
from table_name
WHERE nextuser = 'your string'
AND timestamp = (Select MAX(timestamp) from table_name)
您可以使用 window 函数根据文档名称、文档编号和状态对条目进行排名,如下所示:
SELECT
docName,
docNumber,
status,
prevU,
nextU,
ts,
RANK() OVER (
PARTITION BY
docName,
docNumber,
status
ORDER BY
ts desc
) rnk
FROM docs
基本上这是针对每个 docName、docNumber 和状态所做的,它将 return 基于最近日期的排名。例如,根据您的示例数据,您有四次 'Change Request' 且 docNumber 为“1”,每次都有不同的状态。由于这 4 个整体的状态是唯一的,因此它们排名为 1。对于“用户请求”docNumber“1”和状态 'APPROVAL' 出现两次,您将看到排名为“2020-03-07”的日期为 1,因为这是最近的。
样本结果可以在这个dbfiddle中找到。您可以修改它以包含所有示例数据,以便更好地了解排名的工作原理。
获得完整结果后,您可以按以下过滤条件进行查询:
where rnk = 1 and nextU = 'name'
上述过滤器将 return 该特定用户的最新条目。 Example
此外,请注意,我刚刚更改了示例中的列名称,以方便我使用。
另外,我不完全确定你需要如何分区,所以你可以根据你的要求修改它。
如果它只需要基于 docName 和 docNumber,则只需从 partition by 子句中删除状态列。 scenario
的结果
在您提供 table 名称后尝试此操作:
SELECT *
FROM Abc123 AS a
WHERE NextUser = @MyUser
AND
EXISTS
(
SELECT 1
FROM abc123 AS i
WHERE a.DocumentName = i.DocumentName
AND a.DocumentNumber = i.DocumentNumber
GROUP BY i.DocumentName,
i.DocumentNumber
HAVING MAX(i.Timestamp) = a.Timestamp
)
这应该 return 来自 table 的记录,其中最后一个触摸该记录的 NextUser 与 @MyUser 匹配。
内部查询确定每个文档名称和文档编号的最大时间戳。然后,外部查询通过名称、编号和时间戳进行关联。最后根据你的参数过滤外层查询结果
这应该是可搜索的,并且也可以与 table 上的任何相关索引一起使用。
我是 SQL 的新手;请原谅这个问题的幼稚
假设您有一个 table,其中每一行都有以下条目,所有条目都是 varchar(50):DocumentName、DocumentNumber、Status、PreviousUser、NextUser、Timestamp。时间戳使得字母排序也是按时间顺序排列的。虽然每一行都是唯一的,但不能保证每一行的 DocumentName 和 DocumentNumber 条目都是唯一的。
我想对 returns unique DocumentName、DocumentNumber 和 Status last 该 DocumentName 和 DocumentNumber 的 NextUser 条目(按时间戳测量)与我拥有的字符串匹配。我如何将其格式化为查询?
这是一个示例 table,其中包含示例 returns,可能有助于阐明我的要求。
+================+================+============+==============+==========+============+
| DocumentName | DocumentNumber | Status | PreviousUser | NextUser | Timestamp |
+================+================+============+==============+==========+============+
| Change Request | 1 | PROCESSING | SSMITH | MJONES | 2020 02 01 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 1 | DRAFT | JDOE | SSMITH | 2020 01 01 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 1 | COMPLETE | SSMITH | NULL | 2020 02 22 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 1 | APPROVAL | MJONES | SSMITH | 2020 02 21 |
+----------------+----------------+------------+--------------+----------+------------+
| Change Request | 3 | PROCESSING | JDOE | SSMITH | 2020 04 17 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 1 | APPROVAL | SSMITH | MJONES | 2020 01 01 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 1 | REWORK | MJONES | SSMITH | 2020 03 03 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 1 | APPROVAL | SSMITH | MJONES | 2020 03 07 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 7 | DRAFT | JDOE | SSMITH | 2020 03 17 |
+----------------+----------------+------------+--------------+----------+------------+
| User Request | 7 | APPROVAL | SSMITH | MJONES | 2020 03 19 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 1 | PROCESSING | JDOE | SSMITH | 2020 05 03 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 1 | DRAFT | JDOE | JDOE | 2020 05 02 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 9 | COMPLETE | JDOE | NULL | 2020 06 24 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 13 | DRAFT | JDOE | SSMITH | 2020 07 04 |
+----------------+----------------+------------+--------------+----------+------------+
| Problem Report | 13 | REWORK | SSMITH | JDOE | 2020 07 17 |
+----------------+----------------+------------+--------------+----------+------------+
如果我想匹配JDOE,我应该返回一行:('Problem Report', 13).
如果我想匹配 SSMITH,我应该返回两行:('Change Request', 3) 和 ('Problem Report', 1).
如果我想匹配 MJONES,我应该返回两行:('User Request', 1) 和 ('User Request', 7).
如果我有什么不明确的地方,请告诉我。
这有帮助吗?
Select DISTINCT DocumentName, DocumentNumber, Status
from table_name
WHERE nextuser = 'your string'
AND timestamp = (Select MAX(timestamp) from table_name)
您可以使用 window 函数根据文档名称、文档编号和状态对条目进行排名,如下所示:
SELECT
docName,
docNumber,
status,
prevU,
nextU,
ts,
RANK() OVER (
PARTITION BY
docName,
docNumber,
status
ORDER BY
ts desc
) rnk
FROM docs
基本上这是针对每个 docName、docNumber 和状态所做的,它将 return 基于最近日期的排名。例如,根据您的示例数据,您有四次 'Change Request' 且 docNumber 为“1”,每次都有不同的状态。由于这 4 个整体的状态是唯一的,因此它们排名为 1。对于“用户请求”docNumber“1”和状态 'APPROVAL' 出现两次,您将看到排名为“2020-03-07”的日期为 1,因为这是最近的。
样本结果可以在这个dbfiddle中找到。您可以修改它以包含所有示例数据,以便更好地了解排名的工作原理。
获得完整结果后,您可以按以下过滤条件进行查询:
where rnk = 1 and nextU = 'name'
上述过滤器将 return 该特定用户的最新条目。 Example
此外,请注意,我刚刚更改了示例中的列名称,以方便我使用。
另外,我不完全确定你需要如何分区,所以你可以根据你的要求修改它。
如果它只需要基于 docName 和 docNumber,则只需从 partition by 子句中删除状态列。 scenario
的结果在您提供 table 名称后尝试此操作:
SELECT *
FROM Abc123 AS a
WHERE NextUser = @MyUser
AND
EXISTS
(
SELECT 1
FROM abc123 AS i
WHERE a.DocumentName = i.DocumentName
AND a.DocumentNumber = i.DocumentNumber
GROUP BY i.DocumentName,
i.DocumentNumber
HAVING MAX(i.Timestamp) = a.Timestamp
)
这应该 return 来自 table 的记录,其中最后一个触摸该记录的 NextUser 与 @MyUser 匹配。
内部查询确定每个文档名称和文档编号的最大时间戳。然后,外部查询通过名称、编号和时间戳进行关联。最后根据你的参数过滤外层查询结果
这应该是可搜索的,并且也可以与 table 上的任何相关索引一起使用。