2015-08-10 7 views
-2

У меня есть стол с двумя колонками RequestId и OldRequestId.Извлечь историю записей

  • Если я прохожу RequestId, он должен получить мне конкретную запись.

  • Если номер OldRequestId не является нулевым в полученной записи, он должен также принести старые данные запроса.

  • Он должен продолжаться до OldRequestId.

Может кто-нибудь помочь мне написать наилучший SQL-запрос для этого требования?

enter image description here

+0

Какие СУБД вы с помощью? Oracle? Или SQL Server? Вы добавили теги для обеих систем. –

+0

Я использую SQL Server. –

ответ

4

Вы можете решить эту проблему с помощью рекурсивного Common Table Expression (КТР):

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; 
+0

Будет ли иметь смысл иметь предложение where для 'RequestID' в основном запросе, а не внутри CTE? – Bulat

+0

@Bulat, скорее я чувствую, что было бы более эффективно то, что сейчас. – Rahul

+0

@Rahul вы чувствуете или пытались? – Bulat

1

Ответ зависит от того, насколько глубоко вы хотите, чтобы связать свои старые запросы на их замену. Если это только один уровень, вы можете сделать простой 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) 

Как вы хотите, чтобы связать старые запросы к новейшим вам нужно сделать это рекурсивно с КТР:

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; 
Смежные вопросы