Понимание логика ожидаемого результата
У вас есть довольно сложные требования для вашего ожидаемого результата.Из того, что я понял из вашего SQL скрипку глядя на ожидаемый результат, вы хотите:
- получить первые три должности
- получить первые три комментарии для них
- добавить результат с 1 и 2 с различными логика для столбцов
comment_id
и body
разница в логике, кажется, как показано ниже:
Для каждой строки, представляющей поста:
- в
comment_id
магазине количество комментариев на этот пост
- в
user_id
магазине пользователь, который написал пост
- в
body
магазине тело поста
- в
created_at
хранить отметку времени, когда должность была создана
В то время как для каждой строки, представляющей комментарий логика аналогична (но для комментария, а не сообщения), за исключением столбца comment_id
, где вы хотите сохранить комментарий id
.
запросов и объяснение
Для живого примера взглянуть на SQL fiddle
Во-первых, взять первые три должности и построить строки для их подсчета комментариев для каждого из них. Затем объедините эти столбцы с строками комментариев и используйте функцию row_number()
, чтобы ограничить строки комментариев в выводе до максимум 3 за сообщение.
Присвоение 0
в качестве номера строки для сообщений означает, что они выполняют условие rn <= 3
.
Чтобы сделать вывод по вашему желанию, чтобы для каждого сообщения их комментарии отсортированы сразу после них, я добавил order_column
, чтобы включить его в ORDER BY
.
WITH first_posts AS (
SELECT p.id AS post_id, COUNT(c.id) AS comment_id, p.user_id, p.body, p.created_at
FROM (SELECT * FROM posts ORDER BY id LIMIT 3) AS p
LEFT JOIN comments AS c
ON p.id = c.post_id
GROUP BY 1, 3, 4, 5
)
SELECT post_id, comment_id, user_id, body, created_at
FROM (
SELECT 1 AS type, post_id, comment_id, user_id, body, created_at, 0 AS r
FROM first_posts
UNION ALL
SELECT 2 AS type, p.post_id, c.id, c.user_id, c.body, c.created_at,
ROW_NUMBER() OVER (PARTITION BY p.post_id ORDER BY c.id) AS r
FROM first_posts AS p
INNER JOIN comments AS c
ON p.post_id = c.post_id
ORDER BY post_id, type, comment_id
) AS f
WHERE r <= 3;
Вы имеете в виду первые три должности или первые три сообщения для каждого пользователя? И лучше разместить схему таблицы в сообщении здесь на SO, а также в ссылке ... –
То есть, выход должен быть 9 строк? post1-comm1, post1-comm2, post1-comm3, post2-comm1, ... – Mike
@CharlesBretana Я имел в виду первые три периода сообщений. Я действительно хочу получить первые три сообщения для указанного (не для каждого) пользователя. Но я оставил эту часть, потому что хотел упростить свой вопрос, и решил, что знаю, как изменить запрос на работу для сообщений определенного пользователя, а не всех сообщений. – ma11hew28