2014-10-01 4 views
0

У меня есть таблица, которая имеет два столбца C1 и C2.SQL - group by - limit clause - postgresql

C1 имеет целочисленный тип данных, а C2 имеет текст.

Таблица выглядит так.

---C1--- ---C2--- 
    1 | a | 
    1 | b | 
    1 | c | 
    1 | d | 
    1 | e | 
    1 | f | 
    1 | g | 
    2 | h | 
    2 | i | 
    2 | j | 
    2 | k | 
    2 | l | 
    2 | m | 
    2 | n | 
------------------ 

Мой вопрос: я хочу запрос SQL, который делает группу, на колонке С1, но с размером 3.

выглядит следующим образом.

------------------ 
    1 | a,b,c | 
    1 | d,e,f | 
    1 | g | 
    2 | h,i,j | 
    2 | k,l,m | 
    2 | n | 
------------------ 

Возможно ли это путем выполнения SQL ???

Примечание: Я не хочу, чтобы написать хранимую процедуру или функцию ...

ответ

4

Вы можете использовать общее табличное выражение для разбиения результатов на строки, а затем использовать STRING_AGG, чтобы присоединиться к ним в разделенную запятой списков;

WITH cte AS (
    SELECT *, (ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY C2)-1)/3 rn 
    FROM mytable 
) 
SELECT C1, STRING_AGG(C2, ',') ALL_C2 
FROM cte 
GROUP BY C1,rn 
ORDER BY C1 

An SQLfiddle to test with.

Краткое объяснение общего выражения таблицы;

ROW_NUMBER() OVER (...) будет подсчитывать результаты от 1 до n для каждого значения C1. Затем мы вычитаем 1 и разделим на 3, чтобы получить последовательность 0,0,0,1,1,1,2,2,2... и сгруппируем по этому значению во внешнем запросе, чтобы получить 3 результата в строке.

+1

спасибо ... свою работу .... :) (м не знают ommon табличного выражения, ROW_NUMBER() и PARTITON вещи .... .) –

+0

+1 для четкого объяснения ... еще раз спасибо чувак. –

1

Помимо Joachim Isaksson's answer, вы пытаетесь этот метод

SELECT C1, string_agg(C2, ',') as c2 
FROM (
     SELECT *, (ROW_NUMBER() OVER (PARTITION BY C1 ORDER BY C2)-1)/3 as row_num 
     FROM atable) t 
GROUP BY C1,row_num 
ORDER BY c2 
+0

yup ... его работа .... –