如何在SQL Server中分组几行?

时间:2015-07-05 19:57:18

标签: sql-server database

我有这个问题:

SELECT 
    Table1.ID, Table1.Code1, Table1.Code2, Table1.Details, 
    Table1.IDS, Table2.Name 
FROM 
    Table1 
INNER JOIN 
    Table2 ON Table1.Code1 = Table2.Code1 
WHERE 
    Table1.IDS = 1 
ORDER BY 
    Table1.Code1, Table1.Code2

这是我的查询结果:

ID    Code1   Code2   Details   IDS    Name
1     1001     01       D1       1      N1
2     1001     01       D2       1      N1
3     1001     02       D3       1      N1
4     1001     05       D4       1      N1
5     1002     11       D5       1      N2
6     1002     12       D6       1      N2
7     1005     21       D7       1      N3
8     1005     21       D8       1      N3

但我想要这个结果:

ID    Code1   Code2   Details   IDS    Name
1     1001     01       D1       1      N1
2              01       D2       1
3              02       D3       1
4              05       D4       1
5     1002     11       D5       1      N2
6              12       D6       1
7     1005     21       D7       1      N3
8              21       D8       1

我如何得到这个结果?请帮我。非常感谢

4 个答案:

答案 0 :(得分:1)

在查询中嵌入表示逻辑并不理想。我建议您以编程方式处理查询结果,以便在迭代时检测组的更改,或者将查询结果转换为嵌套表。后者可以概括为可重用的函数。

答案 1 :(得分:0)

如果您可以依赖ID列来排序组(或其他行的组合,如code1,code2),那么您可以通过几种不同的方式执行此操作。

如果您的服务器是2012+,那么您可以使用LAG()窗口函数来访问以前的行,如果前一行Code1与当前行相同Code1将其替换为null(如果适合您,则替换为空字符串)更好)。但是,如果您使用的是版本< 2012年,你可以使用自我加入来完成它。

虽然可以,但在客户端(或报告层)处理这种格式可能更好。

下面的查询包括两个版本,但我注释掉了自联接内容:

main {
  padding:0;
  margin:0;
}

Sample SQL Fiddle

答案 2 :(得分:0)

莫尔塔扎,

这是演示文稿/ UI层要求的明显案例。数据库是为特定目的而制作的,即用于处理数据并向您显示结果。我强烈建议您转向前端逻辑以实现您的目的。

答案 3 :(得分:0)

ROW_NUMBER()CTE中使用subquery,这是获得预期输出的一种方法:

;WITH q1 as
(
SELECT 
    t1.ID, 
    t1.Code1, 
    t1.Code2,
    t1.Details, 
    t1.IDS, 
    t2.Name,
    ROW_NUMBER() OVER (PARTITION BY t1.Code1 ORDER BY t1.ID) as rn
FROM 
    table1 t1 
INNER JOIN 
    Table2 t2 ON t1.Code1 = t2.Code1 
)

SELECT 
    q1.ID, 
    CASE
      WHEN rn = 1 THEN q1.Code1
    ELSE ''
    END as Code1, --only populate first row for each code1
    q1.Code2,
    q1.Details, 
    q1.IDS, 
    CASE
      WHEN rn = 1 THEN q1.Name
    ELSE ''
    END as Name  --only populate first row for each name
FROM 
    q1
WHERE 
    q1.IDS = 1 
ORDER BY 
    q1.Code1, q1.Code2

SQL Fiddle Demo