SQL获取每行最后一次出现的字段

SQL获取每行最后一次出现的字段,sql,sql-server-2008,Sql,Sql Server 2008,如何添加LastDocumentID列,如下所示: +------------+-----------+----------------+ | DocumentID | Reference | LastDocumentID | +------------+-----------+----------------+ | 1 | A | NULL | | 2 | A | 1 | |

如何添加LastDocumentID列,如下所示:

+------------+-----------+----------------+
| DocumentID | Reference | LastDocumentID |
+------------+-----------+----------------+
|          1 | A         | NULL           |
|          2 | A         | 1              |
|          3 | A         | 2              |
|          4 | B         | NULL           |
|          5 | B         | 4              |
|          6 | C         | NULL           |
|          7 | C         | 6              |
|          8 | C         | 7              |
|          9 | C         | 8              |
+------------+-----------+----------------+

表可以是随机顺序,但在最后一个文档ID中,我基本上希望它获得的最大文档ID小于该行引用的该行文档ID。

在SQL Server 2012+中,可以使用lag。在SQLServer2008中,可以使用相关子查询或外部应用。这里有一种方法:

select documentid, reference,
       (select top 1 documentid
        from table t2
        where t2.reference = t.reference and
              t2.documentid < t.documentid
        order by documentid desc
       ) as LastDocumentId
from table t;

我被要求取消删除此项,并附带以下警告。。。对于大于2008的SQL Server版本:

您可以使用窗口函数来实现这一点

SELECT
    DocumentID,
    Reference,
    MAX(DocumentID) OVER (PARTITION BY Reference ORDER BY DocumentID ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS LastDocumentID
FROM
    <table>

这一行较长,窗口函数将从由引用字段划分的行组中获取maxdocumentid,该行受该引用的所有先前DocumentID(不包括当前文档)的限制

您可以通过以下方式从上一个文档中获取任何值:

SELECT
   D.DocumentID,
   D.Reference,
   LastDocumentID = R.DocumentID
FROM
   dbo.Documents D
   OUTER APPLY (
      SELECT TOP 1 *
      FROM dbo.Documents R
      WHERE
         D.Reference = R.Reference
         AND R.DocumentID < D.DocumentID
      ORDER BY R.DocumentID DESC
   ) R
;
或者,您也可以使用Max:

如果这是一种选择,滞后可能更有效。但当MAX工作出色时,没有特别的理由使用TOP

select
    documentid, reference,
    (
        select max(documentid) from table as t2
        where t2.reference = t1.reference and t2.documentid < t1.documentid
    )
from table as t1;

您尝试了什么?SQL Server 2008支持窗口功能,但不支持ROWS子句。您没有在子查询中排序。@shawnt00。谢谢。我认为这也可以使用MAXdocumentid来完成,而不是使用前1个documentid,并省略ORDERBY子句。
SELECT
   D.DocumentID,
   D.Reference,
   LastDocumentID = (
      SELECT Max(R.DocumentID)
      FROM dbo.Documents R
      WHERE
         D.Reference = R.Reference
         AND R.DocumentID < D.DocumentID
   )
FROM
   dbo.Documents D
;
SELECT
    D.DocumentID,
    D.Reference,
    LastDocumentID = Max(D.DocumentID) OVER (
       PARTITION BY D.Reference
       ORDER BY D.DocumentID ASC
       ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
    )
FROM
    dbo.Documents D
;
select
    documentid, reference,
    (
        select max(documentid) from table as t2
        where t2.reference = t1.reference and t2.documentid < t1.documentid
    )
from table as t1;