我想用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执行此操作?
干杯。
答案 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