2013-11-07 3 views
3

Есть ли функциональность в sql, которая может эффективно выполнять это?SQL: group by, упорядочиваем и конкатцируем результаты

Образно, у меня есть база данных с тремя столбцами: tape_date, empl и столбец с одним символом val; Я хочу извлечь последние 3 значения val для каждого empl, объединенных в порядке их tape_date. Например, для таблицы ниже я должен получить строку

bob, DEA 

и аналогично для других empl-х годов. Порядок имеет значение, так что, например, EDA будет неправильным результатом для bob.

Я использую Sybase Adaptive Server Enterprise/15.7.0, но предпочитаю не использовать проприетарные функции.

tape_date empl val 
------------------------ 
2014-01-08 bob  A 
2014-01-01 bob  G 
2014-01-03 alice K 
2014-01-02 bob  D 
2014-01-05 bob  E 
+2

Какая версия SYBASE? –

+1

Это не то, что вы можете сделать легко, не используя собственные функции. –

+0

@DStanley 15.7.0 –

ответ

2

Существует несколько способов сделать это, один из них - использовать функцию SYBASE LIST, если вы не возражаете, чтобы она работала только на Sybase. Если нет, вы можете сделать это с помощью RANK и MAX. Например:

SELECT 
    CAST('2014-01-03' AS DATE) AS tape_date 
    ,'alice' AS empl 
    ,'K' AS val 
INTO #temp_table; 
INSERT INTO #temp_table VALUES('2014-01-08', 'bob', 'A'); 
INSERT INTO #temp_table VALUES('2014-01-01', 'bob', 'G'); 
INSERT INTO #temp_table VALUES('2014-01-02', 'bob', 'D'); 
INSERT INTO #temp_table VALUES('2014-01-05', 'bob', 'E'); 


-- USING SYBASE ONLY LIST FUNCTION 
SELECT empl, SUBSTR(LIST(val ORDER BY tape_date), 1, 5) 
FROM #temp_table 
GROUP BY empl; 

-- THE GENERIC WAY 
SELECT 
    empl 
    ,MAX(CASE rank WHEN 1 THEN val ELSE '' END) 
    + ',' 
    + MAX(CASE rank WHEN 2 THEN val ELSE '' END) 
    + ',' 
    + MAX(CASE rank WHEN 2 THEN val ELSE '' END) 
FROM (
SELECT 
    RANK() OVER (PARTITION BY empl ORDER BY tape_date) AS rank 
    ,* 
FROM #temp_table) a 
WHERE rank <= 3 
GROUP BY 
    empl 
+0

'RANK()' не является общим. Это не было в MS SQL Server до версии 2005. –

+0

@D Стэнли - правда, когда я сказал, что общий, я имел в виду не использовать собственные функции в соответствии с вопросом. В вопросе не указывалось, что он должен быть обратно сопоставим. –

0

Единственный способ «сплющить» строки, возвращенные в группе запроса с использованием процедурного языка (T-SQL, C#, Java). Невозможно только в SQL.

+0

Я никогда не пользовался sybase, но я уверен, что он использует T-SQL – Malachi

+1

Sybase имеет функцию LIST, которая будет сглаживать столбец, значение по умолчанию разделяется запятой, но вы указываете любую комбинацию символов. вы также можете указать, какой порядок вы хотите, чтобы муравей сделал его отдельным списком. –