Sql组行具有相同的值,并将该值放入标头?

时间:2009-06-05 14:10:15

标签: sql

我想用SQL对行进行分组,我的结果集如下:

名称大小日期
DATA1 123 12/03/2009
数据1 124 15/09/2009
DATA2 333 02/09/2010
DATA2 323 02/11/2010
数据2 673 2014年2月9日
DATA2 444 05/01/2010

我想将结果集分组如下:

DATA1
123个12/03/2009
124个15/09/2009
数据2
333个02/09/2010
323个02/11/2010
673个2014年2月9日
444 05/01/2010

是否可以使用纯SQL执行此操作?

干杯。

5 个答案:

答案 0 :(得分:8)

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/ora/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

答案 1 :(得分:3)

提前整理数据简化了应用程序开发人员的工作,特别是如果他们所做的只是显示没有交互式编辑,排序或分页的静态报告 - 这种情况很常见。

Lieven的解决方案(在为其他列插入空值时明确选择列,然后检查其他列的空值)是实际工作的唯一解决方案。那种。

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

Roux提出的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

Pitiş'ROWNUM解决方案可以在Oracle中运行(我没有尝试过,似乎缺少了开头的括号),但使用ROW_NUMBER()OVER的等效SQL Server代码肯定会使工作不好 - 不管怎样作为我的语法和拼写。

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

作为一名软件专业人士,您的工作是确保数十亿的1和0在正确的时间,正确的顺序,在正确的时间排队。你知道细节,往往是一个单独的位,很重要。

一半的答案比没有答案更糟糕,因为它浪费了每个人的时间。因此......没有任何冒犯意图,因为意图是好的,但请至少在将其作为“解决方案”发布之前测试您的“解决方案”。

如果我不那么谦卑,我会很完美。甚至我测试。

答案 2 :(得分:2)

迈克尔·托德在他说这应该在客户端完成时绝对正确,但为了它的乐趣,这是一个选择

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

答案 3 :(得分:1)

可能有类似的内容:

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知道如何做...是在主要选择时将''用于名称,当大小或日期为'时,用case / swich操作)。这里需要一些帮助:)。

正如观察一样,在提供的SQL中,ROWNUM是一个特殊的列,它提供了select的行号(例如,参见Oracle)。

查询显示原则,我不是100%确定它有效。

<强>更新 ......这就是解决方案草图。但我仍然认为这是格式化问题,而不是SQL问题。

答案 4 :(得分:1)

您可以使用两个查询,然后在应用程序代码中进行分组/格式化。

第一次查询

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;
}

生成的group_array就像;

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