Thinking of a forward-looking approach, I thought you might want to work with a framework that allows you to have "grandchildren" from your posts. For that I did the following script
insertion:
CREATE TABLE autor(
id_autor INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
nome VARCHAR(100)
);
go
CREATE TABLE postagem(
id_postagem INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
titulo VARCHAR(100),
id_autor INT,
postagem_pai INT,
CONSTRAINT fk_postagem_autor FOREIGN KEY (id_autor) REFERENCES autor (id_autor),
CONSTRAINT fk_postagem_postagem FOREIGN KEY (postagem_pai) REFERENCES postagem (id_postagem)
);
go
-- Inserções
DECLARE @id_autor INT,
@postagem_pai INT;
-- Insere os autores
INSERT INTO autor(nome)
VALUES('Autor01');
SET @id_autor = SCOPE_IDENTITY();
INSERT INTO autor(nome)
VALUES('Autor02');
-- Insere o pai
INSERT INTO postagem(titulo, id_autor)
VALUES('post_pai', @id_autor);
SET @postagem_pai = SCOPE_IDENTITY();
-- Insere filhos
INSERT INTO postagem(titulo, id_autor, postagem_pai)
VALUES('post_filho1', @id_autor, @postagem_pai),
('post_filho2', @id_autor, @postagem_pai),
('post_filho3', @id_autor, @postagem_pai);
SET @postagem_pai = SCOPE_IDENTITY();
-- Insere netos
INSERT INTO postagem(titulo, id_autor, postagem_pai)
VALUES('post_neto3.1', @id_autor, @postagem_pai)
go
Which produces the following result:
Author table
Posting table
Using WITH
So to produce the selection of all posts I used the expression WITH
of SQL Server
.
WITH common_table_expression
Specifies a temporary named result set, known as a CTE (common table expression). It is derived from a simple query and defined in the execution scope of a single SELECT, INSERT, UPDATE or DELETE statement. This clause can also be used in a CREATE VIEW statement as part of the SELECT statement that defines it. A common table expression can include references to itself. It is what we call the common recursive table expression.
WITH conjunto AS(
-- Aqui vai a seleção do registro base que você desejado (Também chamado de "archor")
SELECT pai.*,
1 AS nivel
FROM postagem pai
-- Aqui você insere o parâmetro que dirá qual postagem é a raiz
WHERE pai.id_postagem = 1
UNION ALL
-- Note que abaixo a select tem um union na declaração do "WITH"
SELECT filho.*,
pai.nivel + 1 AS nivel
FROM postagem filho
-- Aqui se aplica a recursão
INNER JOIN conjunto pai ON pai.id_postagem = filho.postagem_pai
)
SELECT conj.*
FROM conjunto conj
RESULT:
I don’t see the need for this last line "AND C.id_author ...". Because Victor is already doing the Join with these two tables.
– Jeterson Miranda Gomes
got it, my need to stay even clearer, was in this example, bring the posts with the exception of the 50228
– DiChrist
Dichrist think you meant you want to bring all posts except the one of id_postagem=50225 right? If not you will be bringing the post with the value of the column post_parent=0.
– alan