【问题标题】:Fetch history of records获取记录的历史记录
【发布时间】:2015-08-10 10:00:28
【问题描述】:

我的表格包含RequestIdOldRequestId 两列。

  • 如果我传递了RequestId,它应该会检索我的具体记录。

  • 如果OldRequestId在检索到的记录中不为空,它应该也带上旧的请求数据。

  • 应该一直持续到OldRequestId 为空。

有人可以帮我写出满足这个要求的最佳 SQL 查询吗?

【问题讨论】:

  • 您使用的是哪个 DBMS?甲骨文?还是 SQL Server?您为两个系统添加了标签
  • 我正在使用 SQL Server..

标签: sql sql-server tsql


【解决方案1】:

您可以使用递归公用表表达式 (CTE) 解决此问题:

DECLARE
   @RequestID int = 6;

WITH
   ReqCTE AS
      (
         SELECT
               RequestID,
               OldRequestID
            FROM
               Requests
            WHERE
               RequestID = @RequestID
         UNION ALL SELECT
               R.RequestID,
               R.OldRequestID
            FROM
               ReqCTE C
               INNER JOIN Requests R
                  ON R.RequestID = C.OldRequestID
      )
SELECT
      *
   FROM
      ReqCTE;

【讨论】:

  • 在主查询中而不是在 CTE 中使用 RequestID 的 where 子句是否更有意义?
  • @Bulat,我觉得现在的效率会更高。
  • @Rahul 无论您在 CTE 或外部使用条件,执行计划都是相同的。
【解决方案2】:

答案取决于您希望将旧请求与其替换请求关联的深度。如果只是一级,可以做个简单的LEFT JOIN

SELECT  
  n.RequestID,
  COALESCE(r.RequestID, n.RequestID) AS CurrentRequestID,
  n.OldRequestID
FROM
  Requests n LEFT JOIN 
  Requests r ON n.RequestID = r.OldRequestID
WHERE 6 IN (r.RequestID, n.RequestID) 

当您想将旧请求链接到最新请求时,您需要使用 CTE 递归:

WITH CurrentRequests AS (
  SELECT
    id,
    RequestID,
    OldRequestID ,
    RequestID as TopRequestID
  FROM
    Requests
  UNION ALL SELECT
    R.id,
    R.RequestID,
    R.OldRequestID, 
    C.TopRequestID as TopRequestID
  FROM
    CurrentRequests C
    INNER JOIN Requests R
      ON R.RequestID = C.OldRequestID
)
SELECT *
FROM
 CurrentRequests 
WHERE TopRequestID  = 6; 

【讨论】:

    猜你喜欢
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2013-08-02
    • 2018-05-10
    • 2014-11-14
    • 1970-01-01
    相关资源
    最近更新 更多