SQLite: разбиение списка на группы


В этой задаче разбиваем список продуктов на группы по 5 шт.
Вместо функции CAST в других БД можно использовать ceil()

.headers on
.mode column

CREATE TABLE products (
    prod_id INTEGER PRIMARY KEY,
    prod_name VARCHAR(50)
);

INSERT INTO products(prod_name) VALUES ('Prod 1');
INSERT INTO products(prod_name) VALUES ('Prod 2');
INSERT INTO products(prod_name) VALUES ('Prod 3');
INSERT INTO products(prod_name) VALUES ('Prod 4');
INSERT INTO products(prod_name) VALUES ('Prod 5');
INSERT INTO products(prod_name) VALUES ('Prod 6');
INSERT INTO products(prod_name) VALUES ('Prod 7');
INSERT INTO products(prod_name) VALUES ('Prod 8');
INSERT INTO products(prod_name) VALUES ('Prod 9');
INSERT INTO products(prod_name) VALUES ('Prod 10');
INSERT INTO products(prod_name) VALUES ('Prod 11');
INSERT INTO products(prod_name) VALUES ('Prod 12');


SELECT cast((rank/5) as int) as grpno, prod_id, prod_name
FROM (
	SELECT A.prod_id, A.prod_name,
		   (select count(*) from products B where A.prod_id > B.prod_id) as rank
	FROM products A
) X
ORDER BY grpno
;

Примерно по такому же алгоритму можно разбить список на заданное число групп:

SELECT (count(*)%3)+1 as grpno,
        A.prod_id, A.prod_name
FROM products A, products B
WHERE A.prod_id >= B.prod_id
GROUP BY A.prod_id, A.prod_name
ORDER BY 1;


Но самое простое решение - разделить номер строки на кол-во блоков и округлить:

SELECT
  ceil(row_number() over (order by prod_name)/5.0) as grpno,
  prod_name
FROM products

Если же групп должно быть точно заданное число, то можно применить функцию mod()

SELECT
    mod(row_number()over(order by prod_name),4)+1 grp,
    prod_name
FROM products

#