Eu tenho que seguir os dados no SQL Server 2008 R2. SQLFiddle
Esquema:
CRIAR TABELA [dbo].[ICFilters]( [ICFilterID] [int] IDENTITY(1,1) NOT NULL, [ParentID] [int] NÃO NULO PADRÃO 0, [FilterDesc] [varchar](50) NÃO NULO, [Ativo] [tinyint] NÃO NULO PADRÃO 1, CONSTRAINT [PK_ICFilters] CHAVE PRIMÁRIA CLUSTERED ( [ICFilterID] ASC ) COM PAD_INDEX = DESLIGADO, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = DESLIGADO, ALLOW_ROW_LOCKS = ATIVADO, ALLOW_PAGE_LOCKS = ATIVADO ) EM [PRIMÁRIO] ) EM [PRIMÁRIO] INSERT INTO [dbo].[ICFilters] (ParentID,FilterDesc,Active) Valores (0,'Tipo de produto',1), (1,'ProdSubType_1',1), (1,'ProdSubType_2',1), (1,'ProdSubType_3',1), (1,'ProdSubType_4',1), (2,'PST_1.1',1), (2,'PST_1.2',1), (2,'PST_1.3',1), (2,'PST_1.4',1), (2,'PST_1.5',1), (2,'PST_1.6',1), (2,'PST_1.7',0), (3,'PST_2.1',1), (3,'PST_2.2',0), (3,'PST_2.3',1), (3,'PST_2.4',1), (14,'PST_2.2.1',1), (14,'PST_2.2.2',1), (14,'PST_2.2.3',1), (3,'PST_2.8',1)
Mesa:
| ICFILTERID | PARENTID | FILTERDESC | ATIVO | -------------------------------------------------- | 1 | 0 | Tipo de produto | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 3 | 1 | ProdSubType_2 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1.5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 20 | 3 | PST_2.8 | 1 |
Cada linha tem o ID de seu pai e o parentid = 0
. Os FilterDesc
s são apenas descrições de amostra, então não posso tentar analisá-los para fazer o pedido.
A questão
É possível selecionar todas as linhas de maneira semelhante a uma árvore? Se sim, como? Quando digo 'semelhante a uma árvore', quero dizer selecionar recursivamente o pai seguido por todos os seus filhos, depois todos os filhos de cada um deles e assim por diante. Uma travessia da primeira árvore de profundidade.
Meus amigos e eu tentamos, mas ficamos aquém das soluções de trabalho, mas continuaremos tentando. Eu sou bastante novo no sql, então talvez isso possa ser feito facilmente e estou apenas tornando as coisas mais difíceis do que o necessário.
Exemplo de saída (desejada):
| ICFILTERID | PARENTID | FILTERDESC | ATIVO | -------------------------------------------------- | 1 | 0 | Tipo de produto | 1 | | 2 | 1 | ProdSubType_1 | 1 | | 6 | 2 | PST_1.1 | 1 | | 7 | 2 | PST_1.2 | 1 | | 8 | 2 | PST_1.3 | 1 | | 9 | 2 | PST_1.4 | 1 | | 10 | 2 | PST_1.5 | 1 | | 11 | 2 | PST_1.6 | 1 | | 12 | 2 | PST_1.7 | 0 | | 3 | 1 | ProdSubType_2 | 1 | | 13 | 3 | PST_2.1 | 1 | | 14 | 3 | PST_2.2 | 0 | | 17 | 14 | PST_2.2.1 | 1 | | 18 | 14 | PST_2.2.2 | 1 | | 19 | 14 | PST_2.2.3 | 1 | | 15 | 3 | PST_2.3 | 1 | | 16 | 3 | PST_2.4 | 1 | | 20 | 3 | PST_2.8 | 1 | | 4 | 1 | ProdSubType_3 | 1 | | 5 | 1 | ProdSubType_4 | 1 |
OK, células cerebrais suficientes estão mortas.
SQL Fiddle
O acima não parece funcionar corretamente para mim. Imagine uma configuração de 2 mesas com dados do tipo facebook. Tabela 1, tem PostId + seus outros campos. PostId é um incremento automático e, obviamente, em sua interface, você classificará DESC para ter a postagem mais recente no topo.
Agora para a tabela de comentários. Tabela 2 Esta tabela CommentId é a chave primária, número automático. Em seu gui, você deseja exibi-lo em ASC, para que, ao ler o thread, faça sentido. (o mais antigo (número menor) no topo) Outras chaves importantes na tabela 2 são: PostId (FK de volta às postagens) e ParentId (FK a CommentId) onde ParentId será NULL se este for o comentário "raiz" em uma postagem. Se alguém RESPONDER a um comentário, o parentId será preenchido com o commentid.
Espero que tenham entendido. O CTE ficará assim:
Saída de amostra
Na postagem 105 do F/B, houve dois comentários (CommentIds 1 e 2) Alguém respondeu em Comment1 (CommentId 5, ParentId 1) e, em seguida, outra pessoa comentou essa resposta, então em Comment5 (CommentId 6, ParentId 6)
E viola, a sequência está correta, abaixo do post, agora você pode mostrar os comentários na sequência correta. Para recuar as postagens para que se forme e contorne como no facebook (quanto mais profundo o nível, mais deve ser marginalizado da esquerda), também tenho uma coluna chamada Recuar. As raízes são 0 e, em seguida, na união, temos c.Indent + 1 AS Indent No código, agora você pode multiplicar o recuo com vamos supor 32px e mostrar os comentários em uma boa hierarquia e contorno.
Não vejo nenhum problema em usar a chave primária de incremento automático CommentId como a força motriz para construir minha SortKey, pois há uma mudança melhor de você bagunçar datas (commentdate) do que bagunçar uma chave gerenciada de banco de dados que semeia com +1
Isso lhe dará todos os descendentes e o nível.
Espero que isto ajude :)