Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Ricorsivo cte sql con per livello gerarchico

Non ci hai detto come fai a sapere se un utente ha i diritti su un determinato ID. Questa è un'informazione necessaria. Di seguito inserirò del codice che presuppone che tu aggiunga una colonna alla tua query chiamata hasRights e che questa colonna avrà un valore zero se l'utente non ha diritti e un valore di uno se lo ha. Potrebbe essere necessario modificarlo, dal momento che non ho dati con cui testare, ma spero che ti avvicini.

Fondamentalmente, la query viene modificata per aggiungere 1 solo al livello se l'utente dispone dei diritti. Inoltre si aggiunge al percorso di ordinamento solo se l'utente dispone dei diritti, altrimenti viene aggiunta una stringa vuota. Quindi, se gli ID 8 e 9 sono gli unici elementi a cui l'utente ha accesso, dovresti vedere i livelli 1 e 2 e ordinare i percorsi in modo simile a "5/8/9" anziché "5/6/8/9". Se ancora non riesci a farlo funzionare, ci aiuterebbe enormemente se pubblicassi uno schema di esempio su SqlFiddle.

WITH Tree
AS (
SELECT
    id,
    parent,
    0 AS Level,
    id AS Root,
    hasRights AS HasRights,
    CAST(id AS VARCHAR(MAX)) AS Sort,
    user_id
FROM SourceTable
WHERE parent IS NULL

UNION ALL

SELECT 
    st.id,
    st.parent,
    Level + st.hasRights AS Level,
    st.parent AS Root,
    st.hasRights AS HasRights,
    uh.sort + CASE st.hasRights WHEN 0 THEN '' ELSE '/' + CAST(st.id AS VARCHAR(20)) END AS Sort,
    st.user_id
FROM SourceTable AS st
    JOIN Tree uh ON uh.id = st.parent    
)

SELECT * FROM Tree AS t
    JOIN UserTable AS ut ON  ut.id = t.user_id AND ut.user_id = '141F-4BC6-8934'
ORDER BY Sort