如何根据具有最后时间戳的行筛选SQL结果



我对SQL相当陌生;请原谅这个问题的天真。

假设您有一个表,其中每行都有以下条目,它们都是varchar(50(:DocumentName、DocumentNumber、Status、PreviousUser、NextUser、Timestamp。时间戳是这样的,字母排序也是按时间顺序排列的。虽然每一行都是唯一的,但不能保证每一行上的DocumentName和DocumentNumber条目都唯一。

我想创建一个查询,为所有文档返回唯一的DocumentName、DocumentNumber和Status,其中该DocumentName和DocumentNumber的最后一个NextUser条目(通过时间戳测量(与我拥有的字符串相匹配。如何将其格式化为查询?

下面是一个带有示例返回的示例表,它可能有助于澄清我的要求。

+================+================+============+==============+==========+============+
| 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,我应该返回一行:("问题报告",13(。

如果我想匹配SSMITH,我应该返回两行:("更改请求",3(和("问题报告",1(。

如果我想匹配MJONES,我应该返回两行:("用户请求",1(和("用户申请",7(。

如果我留下了不明确的地方,请告诉我。

一旦提供了表名,请尝试此操作:

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
)

这应该返回表中的记录,其中最后一个接触记录的NextUser与@MyUser匹配。

内部查询标识每个文档名称&文件编号。然后通过名称、编号和时间戳来关联外部查询。最后,外部查询结果由您的参数进行过滤。

这应该是可搜索的,并与表上的任何相关索引一起使用。

这有帮助吗?

Select DISTINCT DocumentName, DocumentNumber, Status
from table_name
WHERE nextuser = 'your string'
AND timestamp = (Select MAX(timestamp) from table_name)

您可以使用一个窗口函数,根据docName、docNumber和状态对条目进行排名,如下所示:

SELECT
docName,
docNumber,
status,
prevU,
nextU,
ts,
RANK() OVER (
PARTITION BY
docName,
docNumber,
status
ORDER BY
ts desc
) rnk
FROM docs

基本上,这对每个docName、docNumber和状态都会返回一个基于最近日期的排名。例如,根据您的示例数据,您有docNumber为"1"的"变更请求",四个不同的时间,每个时间具有不同的状态。由于这4个实体的状态是唯一的,因此它们被列为1。对于";用户请求";docNumber"1"和状态"APPROVAL"出现两次,您将看到日期"2020-03-07"排名为1,因为这是最近的一次。

样本结果可以在这个数据库中找到。您可以修改它以包括所有样本数据,从而更好地了解排名的工作方式。

一旦你有了完整的结果,你可以查询以下过滤条件:

where rnk = 1 and nextU = 'name'

上面的过滤器将返回该特定用户的最新条目。示例

另外,请注意,我刚刚更改了示例中的列名,使其对我来说更容易

另一件事,我不完全确定你需要如何对它进行分区,所以你可以根据你的需求进行修改。

如果它只需要基于docName和docNumber,那么只需从partitionby子句中删除status列。此场景的结果

最新更新