SQL,使用rank生成列

时间:2017-09-12 15:20:37

标签: sql-server rank

我有一个属性的占用者列表,需要操纵数据,因此它将属性显示为一行,每个额外的占用者出现在新列中。

以下是我迄今为止所做的事情:

providers: [AuthService],

Your ng module should be like:

@NgModule({
      declarations: [
        AppComponent,
        LoginComponent,
        HeaderComponent,
     ],
      imports: [
        BrowserModule,
        RoutingModule
      ],
      providers: [AuthService],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

RANKING中的查询输出下表:

if (!empty($locale)) { 
    $_SESSION['code'] = 'en';
    foreach($langs as $lang) {
        if($lang['code'] == $locale){
            $_SESSION['code'] = $lang['code'];
            break;
        }
    }
}

然后我尝试使用排名值创建列,如下所示:

with RANKING AS 
(   Select 
    Postcode
    , Number
    , Occupant
    , RANK() OVER
    (Partition by Postcode order by Occupant) as [Rank]

from Reporting.dbo.Test --order by [Rank] desc
)

现在,2个问题:

1)有没有办法自动化这个过程,所以对于x的等级,我们有x个租户行

2)此输出的表是

Postcode | Number | Occupant | Rank
AA001AA  |  12    |    D     |  1
AA001AA  |  12    |    E     |  2
AA001AA  |  12    |    K     |  3
AA001AA  |  12    |    M     |  4
AA001AA  |  12    |    T     |  5
BB001BB  |   8    |    M     |  1
BB001BB  |   8    |    R     |  2

如何压缩此列表,以便每个邮政编码只有一行,并且所有非空值都显示在该行上。

2 个答案:

答案 0 :(得分:0)

要先回答您的第二个问题(如何压缩列表),最简单的方法就是group by postcodenumber。您可以只取每列的max()(即,如果有值,则会选择它;所有空值都会丢失)。

要回答第一个问题(这可以自动化),您可能想要研究动态支点。评论中发表的一篇文章是:SQL Server dynamic PIVOT query?

这个想法基本上是序列化不同的tennants,并将其连接到一个执行数据透视的动态S​​QL字符串。有几种方法可以遮盖这只猫,但这就是我接触它的方法。

use tempdb
go

if object_id('tempdb.dbo.#data') is not null drop table #data
create table #data
(
    PostCode varchar(10),
    Number int,
    Occupant char(1),
    Rnk int,
    ColName as 'Tennant ' + cast(Rnk as varchar(10))

)

insert into #Data(PostCode, Number, Occupant, Rnk)
select 'AA001AA', 12, 'D',1
union all select 'AA001AA', 12, 'E',2
union all select 'AA001AA', 12, 'K',3
union all select 'AA001AA', 12, 'M',4
union all select 'AA001AA', 12, 'T',5
union all select 'BB001BB',  8, 'M',1
union all select 'BB001BB',  8, 'R',2

declare 
    @PivotColumns nvarchar(max),
    @SelectColumns nvarchar(max),
    @sql nvarchar(max)

select 
    @PivotColumns = stuff((select ',' + quotename(ColName)
                      from #data
                      group by ColName
                      order by ColName
                      for xml path('')), 1, 1, ''),
    @SelectColumns = stuff((select ',' + quotename(ColName) + ' = max(' + quotename(ColName) + ')'
                            from #data
                            group by ColName
                            order by ColName
                            for xml path('')), 1, 1, ''),
    @sql = '
        select 
            PostCode, 
            Number,
            ' + @SelectColumns + '
        from #data d
        pivot (max(Occupant) for ColName in (' + @PivotColumns + ' )) p
        group by PostCode, Number'


print @sql
exec sp_executesql @sql

答案 1 :(得分:0)

您可以使用动态数据透视来获得结果。请参阅下面的代码 -

create  table #tab (Postcode varchar(10) , Number int , Occupant char(1) , Rank int)

insert into #tab
select 'AA001AA'  ,  12    ,    'D'     ,  1
union all select 'AA001AA'  ,  12    ,    'E'     ,  2
union all select 'AA001AA'  ,  12    ,    'K'     ,  3
union all select 'AA001AA'  ,  12    ,    'M'     ,  4
union all select 'AA001AA'  ,  12    ,    'T'     ,  5
union all select 'BB001BB'  ,   8    ,    'M'     ,  1
union all select 'BB001BB'  ,   8    ,    'R'     ,  2
union all select 'CC001CC'  ,   8    ,    'N'     ,  1
union all select 'CC001CC'  ,   8    ,    'O'     ,  2
union all select 'CC001CC'  ,   8    ,    'P'     ,  3
union all select 'CC001CC'  ,   8    ,    'Q'     ,  4
union all select 'CC001CC'  ,   8    ,    'R'     ,  5
union all select 'CC001CC'  ,   8    ,    'S'     ,  6
union all select 'CC001CC'  ,   8    ,    'T'     ,  7
union all select 'CC001CC'  ,   8    ,    'U'     ,  8
union all select 'CC001CC'  ,   8    ,    'V'     ,  9
union all select 'CC001CC'  ,   8    ,    'W'     ,  10

declare @mx int , @min int = 1 , @sql nvarchar(max) = '' , @select1 nvarchar(max) = '',@select2 nvarchar(max) = ''

select @mx = MAX(rank) from #tab

while @min<= @mx
begin
set @select1  = @select1 + '[' + cast(@min as varchar(10))+ '] ,' 
set @select2  = @select2 + '[' + cast(@min as varchar(10))+ ']  as '+ '[Tennant_' + cast(@min as varchar(10))+ '] ,' 
set @min = @min + 1
end 

set @select1  = SUBSTRING( @select1 , 1 , LEN(@select1)-1)
set @select2  = SUBSTRING( @select2 , 1 , LEN(@select2)-1)


set @sql = '
 SELECT Postcode    , Number ,'+@select2+'
FROM  #tab
PIVOT
(
    max(Occupant)
    FOR [Rank] IN ('+@select1+')
)AS pvt '

 exec sp_executesql @sql