Sql группировать строки с одинаковым значением и помещать это значение в заголовок? - PullRequest
5 голосов
/ 05 июня 2009

Я хочу сгруппировать строки с SQL, мой набор результатов следующий

Имя Размер Дата
data1 123 12/03/2009
data1 124 15/09/2009
data2 333 02/09/2010
data2 323 02/11/2010
data2 673 02/09/2014
data2 444 01.05.2010

Я хочу сгруппировать набор результатов так:

data1
123 12/03/2009
124 15.09.2009
data2
333 02.09.2010
323 02/11/2010
673 02.09.2014
444 01.05.2010

возможно ли это сделать с помощью чистого SQL?

Приветствие.

Ответы [ 5 ]

8 голосов
/ 05 июня 2009

GROUP BY WITH ROLLUP (вы на самом деле не группируете - поэтому вы бы в действительности GROUP BY каждый столбец)

http://dev.mysql.com/doc/refman/5.0/en/group-by-modifiers.html

http://chiragrdarji.wordpress.com/2008/09/09/group-by-cube-rollup-and-sql-server-2005/

http://databases.about.com/od/sql/l/aacuberollup.htm

http://www.adp -gmbh.ch / ора / SQL / group_by / group_by_rollup.html

http://msdn.microsoft.com/en-us/library/bb522495.aspx

На основании кода Ливена:

DECLARE @Table TABLE (
     name varchar(32)
    ,Size integer
    ,Date datetime
    )

INSERT  INTO @Table
VALUES  ('data1', 123, GETDATE())
INSERT  INTO @Table
VALUES  ('data1', 124, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 333, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 323, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 673, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 444, GETDATE())

SELECT  *
FROM    (
         SELECT *
         FROM   @Table
         GROUP BY NAME
               ,size
               ,date
                WITH ROLLUP
        ) AS X
WHERE   NAME IS NOT NULL
        AND (
             (
              Size IS NOT NULL
              AND Date IS NOT NULL
             )
             OR (
                 Size IS NULL
                 AND date IS NULL
                )
            )
ORDER BY NAME
       ,size
       ,date
3 голосов
/ 25 мая 2011

Формирование данных заблаговременно упрощает вещи для разработчика приложений, особенно если все, что они делают, это отображают статический отчет без интерактивного редактирования, сортировки или подкачки страниц - довольно распространенное явление.

Решение Ливена (отличительный выбор столбцов при вставке нулей для других столбцов, а затем проверка нулей других столбцов) - единственное решение, которое действительно работает. Вид.

data1   NULL    NULL
NULL    123 2011-05-24 19:42:29.577
NULL    124 2011-05-24 19:42:29.577
data2   NULL    NULL
NULL    323 2011-05-24 19:42:29.577
NULL    333 2011-05-24 19:42:29.577
NULL    444 2011-05-24 19:42:29.577
NULL    673 2011-05-24 19:42:29.577

- если в столбце, который вы обнуляете, уже нет нулей, в этом случае мы возвращаемся к квадрату 0. Добавьте еще одну строку.

INSERT INTO @Table VALUES ('data2', NULL, getdate())

Теперь снова запустите запрос. Облом чувак.

data1   NULL    NULL
NULL    123 2011-05-24 19:53:36.437
NULL    124 2011-05-24 19:53:36.437
data2   NULL    NULL
data2   NULL    2011-05-24 19:53:36.440
NULL    323 2011-05-24 19:53:36.440
NULL    333 2011-05-24 19:53:36.440
NULL    444 2011-05-24 19:53:36.440

Предлагаемое ROX решение ROLLUP вообще не работает, по крайней мере, в SQL Server. На самом деле, все становится еще хуже.

data1   NULL    NULL
data1   NULL    NULL
data1   NULL    NULL
data1   123 2011-05-24 20:16:26.693
data1   124 2011-05-24 20:16:26.693
data2   NULL    NULL
data2   NULL    NULL
data2   NULL    NULL
data2   323 2011-05-24 20:16:26.693
data2   333 2011-05-24 20:16:26.693
data2   444 2011-05-24 20:16:26.693
data2   673 2011-05-24 20:16:26.693

Решение POWș ROWNUM может работать в Oracle (я не пробовал его и, похоже, отсутствуют начальные скобки), но эквивалентный код SQL Server с использованием ROW_NUMBER () OVER определенно не работает ни на что не годится - тоже как мой грамматик и правописание.

SELECT 
    ROW_NUMBER() OVER(ORDER BY [name]) AS [rown]
    , name
    , ''
    , ''
FROM @Table
GROUP BY name

UNION ALL

SELECT ROW_NUMBER() OVER(ORDER BY [name]) + 1 AS [rown] , name, size, date 
FROM @Table 

производит

data1   NULL    NULL
data1   NULL    NULL
data1   NULL    NULL
data1   123 2011-05-24 20:16:26.693
data1   124 2011-05-24 20:16:26.693
data2   NULL    NULL
data2   NULL    NULL
data2   NULL    NULL
data2   323 2011-05-24 20:16:26.693
data2   333 2011-05-24 20:16:26.693
data2   444 2011-05-24 20:16:26.693
data2   673 2011-05-24 20:16:26.693

Как профессионал в области программного обеспечения, ваша задача - обеспечить, чтобы миллиарды единиц и нулей располагались в нужном месте, в нужном порядке и в нужное время. Вы знаете, детали, часто до отдельных битов, важны.

Половина обширного ответа хуже, чем вообще никакого ответа, потому что он тратит время каждого. Так что ... не обижайте, потому что намерения хорошие, но, по крайней мере, протестируйте свое "решение", прежде чем публиковать его как "решение".

Я был бы идеален, если бы не был так чертовски скромен. И даже я проверяю.

2 голосов
/ 05 июня 2009

Майкл Тодд определенно прав, когда говорит, что это должно быть сделано на стороне клиента, но для удовольствия, это один из вариантов

DECLARE @Table TABLE (name VARCHAR(32), Size INTEGER, Date DATETIME)

INSERT INTO @Table VALUES ('data1', 123, getdate())
INSERT INTO @Table VALUES ('data1', 124, getdate())
INSERT INTO @Table VALUES ('data2', 333, getdate())
INSERT INTO @Table VALUES ('data2', 323, getdate())
INSERT INTO @Table VALUES ('data2', 673, getdate())
INSERT INTO @Table VALUES ('data2', 444, getdate())

INSERT INTO @Table 
SELECT DISTINCT name, NULL, NULL
FROM @Table

SELECT 
  CASE WHEN Size IS NULL THEN Name ELSE NULL END
  , Size
  , Date
FROM @Table
ORDER BY Name, Size
1 голос
/ 27 января 2017

Вы можете использовать два запроса, а затем группировать / форматировать в коде приложения.

Первый запрос

SELECT DISTINCT(name) AS group_name FROM TABLE ORDER BY name LIMIT 5;

Второй запрос

SELECT size, date FROM TABLE WHERE name IN ('comma separated group_name values from firstQueryResult');

Код приложения

for every row in firstQueryResult{
    group_array[group_name] = secondQueryResult;
}

Полученный массив_групп будет выглядеть так:

data1
  123  12/03/2009
  124  15/09/2009
data2
  333  02/09/2010
  323  02/11/2010
  673  02/09/2014
  444  05/01/2010
1 голос
/ 05 июня 2009

Может быть что-то вроде:

select name, size, date from
(
-- select only distinct rows, and empty values for size and date (header rows)
select ROWNUM rown, name, '', ''
from T
group by name
order by name

union all

-- select all data (non-header records)
select ROWNUM+1 rown, name, size, date 
from T 
order by name
)
order by name, rown

Пояснение: Сначала выберите из объединения выбирает записи для заголовка группы. Сортирует результаты по имени. Номер строки дает порядок. Второй выбор из объединения выбирает все записи для заголовка группы. Он сортирует результаты по имени, а номер строки определяет порядок. Союз собрал всю информацию. ROWNUM + 1 для второго выбора гарантирует, что записи для заголовка (из первого выбора) упорядочены до подробных записей.

Теперь ... что вам нужно сделать, и я не могу восстановить столько SQL, чтобы знать, как это сделать ... это поставить '' для имени, когда размер или дата '', в главном select с делом / операция). Здесь нужна помощь:).

Так же, как наблюдение, в предоставленном SQL ROWNUM - это специальный столбец, который предоставляет номер строки для выбора (см., Например, Oracle).

Запрос отображается в принципе, я не уверен на 100%, что он работает.

Обновление: ... это эскиз решения. Но я все еще считаю, что это проблема форматирования, а не проблема SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...