Files
blog-server/internal/db/query/post.sql
2026-07-22 17:50:33 +08:00

145 lines
3.9 KiB
SQL

-- name: CreatePost :one
INSERT INTO posts(title, cover_id, slug, content, summary, status, sort, published_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id;
-- name: ListPosts :many
WITH paginated_posts AS (
-- 第一步:先精准查出当前页需要的文章 ID
SELECT id,
title,
cover_id,
slug,
summary,
status,
sort,
published_at,
created_at,
updated_at
FROM posts
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
-- 第二步:用这极少量的记录去进行 JOIN
SELECT p.*,
f.file_path AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view
FROM paginated_posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
ORDER BY p.sort DESC, p.published_at DESC, p.id DESC;
-- name: CountPosts :one
SELECT COUNT(*)
FROM posts;
-- name: GetPostById :one
SELECT p.*,
f.file_path AS cover,
c.name AS category_name,
c.id AS category_id
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
WHERE p.id = $1
LIMIT 1;
-- name: UpdatePost :execrows
UPDATE posts
SET title = coalesce(sqlc.narg('title'), title),
cover_id = coalesce(sqlc.narg('cover_id'), cover_id),
slug = coalesce(sqlc.narg('slug'), slug),
content = coalesce(sqlc.narg('content'), content),
summary = coalesce(sqlc.narg('summary'), summary),
status = coalesce(sqlc.narg('status'), status),
sort = coalesce(sqlc.narg('sort'), sort),
published_at = coalesce(sqlc.narg('published_at'), published_at)
WHERE id = sqlc.arg('id');
-- name: DeletePost :execrows
DELETE
FROM posts
WHERE id = $1;
-- web -------------------------------------------------------
-- name: GetPublicPostBySlug :one
SELECT p.*,
f.file_path AS cover,
COALESCE(ps.view, 0) AS view
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
WHERE p.slug = $1
AND p.status = 1
AND p.published_at < NOW()
LIMIT 1;
-- name: ListPublishedPosts :many
WITH paginated_posts AS (
-- 第一步:先精准查出当前页需要的文章 ID
SELECT id,
title,
cover_id,
slug,
summary,
sort,
published_at
FROM posts
WHERE status = 1
AND published_at < NOW()
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
SELECT p.*,
f.file_path AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view
FROM paginated_posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
ORDER BY p.sort DESC, p.published_at DESC, p.id DESC;
-- name: CountPublishedPosts :one
SELECT COUNT(*)
FROM posts
WHERE status = 1
AND published_at < NOW();
-- name: ListArchives :many
SELECT
p.id,
p.slug,
p.title,
p.published_at,
c."name" AS category_name
FROM
posts p
LEFT JOIN post_category pc ON p.id = pc.post_id
LEFT JOIN categories c ON c.id = pc.category_id
WHERE
p.status = 1
AND p.published_at < NOW()
ORDER BY
p.published_at DESC, p.id DESC;
-- name: ListCategoryStats :many
SELECT
c.id,
c.name,
COUNT(p.id) AS post_count
FROM
categories c
LEFT JOIN post_category pc ON c.id = pc.category_id
LEFT JOIN posts p ON p.id = pc.post_id
AND p.status = 1
AND p.published_at < NOW()
GROUP BY
c.id,
c.name;