Рекурсивный SQL JOIN без функции или курсора? - PullRequest
3 голосов
/ 22 марта 2012

У меня есть таблица, в которой содержится список уголовных обвинений. Эти обвинения могут быть заменены ... например, если парень был обвинен в нападении, но во время судебного разбирательства жертва умирает, поэтому обвинение заменяется убийством.

У нас есть таблица Подстановки, которая содержит From_Offence и To_Offence. Когда начисление заменено, мы создаем новое начисление, а затем в таблице подстановок записываем идентификатор From, а затем новый To_Id.

CREATE TABLE [dbo].[ijis_court_item_association](
    [ijis_court_item_association_id] [int] IDENTITY(1,1) NOT NULL,
    [from_ijis_court_item_id] [int] NOT NULL,
    [to_ijis_court_item_id] [int] NOT NULL
)

Заряд можно заменить много раз. Итак, Заряд 1 стал Зарядом 2, но потом - Зарядом 3. А затем, возможно, Заряд 3 станет Зарядом 4.

Вы бы получили:

FROMID  TOID
1        2
2        3
3        4

Требуется вернуть список идентификаторов сборов на основе текущего идентификатора сборов.

Итак, по-английски разработчик передаст мне ChargeID: 4, и мне нужно вернуть историю этого заряда (включая его самость). И мой набор результатов будет:

4
3
2
1

Может быть, я могу сделать функцию GetPreviousChargeId, а затем каким-то образом рекурсивно сделать что-нибудь? Но я надеялся, что может быть разумный способ сделать это.

Надеюсь, что есть способ.

1 Ответ

2 голосов
/ 22 марта 2012

Я считаю, что это должно работать. Как уже упоминалось, это рекурсивный CTE

WITH Charges AS
(
    --This should not be just a SELECT 4 because if no matches are found
    --then it will return a null and not recurse at all
    --This query will only run once at the beginning 
    --(it is the anchor to the recursion)
    SELECT to_ijis_court_item_id AS CourtID
    FROM ijis_court_item_association
    WHERE to_ijis_court_item_id = 4

    UNION ALL

    --This is the actual recursion, continuing to query until no results are found
    --It uses the first queries data to begin
    SELECT from_ijis_court_item_id AS CourtID
    FROM ijis_court_item_association
        JOIN Charges
            ON Charges.CourtID = ijis_court_item_association.to_ijis_court_item_id 
)
--This is the final output from all of the above queries (however many there are) 
--union all'ed together
SELECT * FROM Charges;
...