Можно ли вывести в sql лимит статей для каждой категории?

Рейтинг: 0Ответов: 1Опубликовано: 28.07.2023

У меня выводятся статьи по категориям массивом.

$sql = "SELECT
                articles.id AS id,
                articles.title AS title,
                articles.text AS text,
                articles.author AS author,
                articles.image AS image,
                menu.name AS categ
            FROM
                articles
            LEFT JOIN
                menu
            ON
                articles.cat = menu.id
            WHERE
                articles.cat IN ($menu)
            ORDER BY
                menu.name";

Мне нужно поставить limit не для всего массива статей, а для каждой категории выводимых статей. Вот с помощью $menu сейчас выводятся категории по числам 1,2,3 и в итоге получается 6 статей по 2 в каждой категории. Нужно чтобы вывелось например 3 статьи если limit 1. Возможно ли это как-то сделать именно через sql? Сейчас я ставлю допустим limit 1, но тогда из 6 статей выводится только 1 и так получается неправильно

Ответы

▲ 0Принят

Пример для MySQL 8.0:

SELECT 
    category,
    title
FROM (
    SELECT 
        c.name as category,
        a.title,
        row_number() OVER (
            PARTITION BY c.name
        ) AS row_num
    FROM articles a
    INNER JOIN categories c 
        ON c.id = a.category_id
        AND categories.id IN (1, 3)
    # или WHERE categories.id IN (1, 3) 
    ) t
WHERE row_num <= 2; // по 2 articles для каждой категории (categories)

example schema SQL:

create table articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(9),
    category_id INT
);
create table categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50)
);

INSERT INTO categories (name) 
    VALUES 
('first'),('second'),('third');

INSERT INTO articles (title, category_id) 
    VALUES 
('One 1', 1),('One 2', 1),('One 3', 2),('One 4', 2),
('Two 1', 3),('Two 2', 3),('Two 3', 4),('Two 4', 4),
('Three 1', 1),('Three 2', 2),('Three 3', 3),('Three 4', 4),
('Four 1', 1),('Four 2', 2),('Four 3', 3),('Four 4', 4);

UPD. пример исп. LATERAL JOIN:

SELECT
    categories.name as category, 
    articles.title
FROM categories
INNER JOIN LATERAL
(
    SELECT title
    FROM articles
    WHERE articles.category_id = categories.id
    LIMIT 2
) AS articles
WHERE categories.id IN (1,3)