Sql 多级交叉表动态查询
我试图找到一个可以在多个级别动态生成交叉表输出的查询。我确实在网上找到了一些返回动态交叉表结果的解决方案,但它只在单个级别返回。下面是SQL FIDLE:Sql 多级交叉表动态查询,sql,sql-server-2008,tsql,pivot,Sql,Sql Server 2008,Tsql,Pivot,我试图找到一个可以在多个级别动态生成交叉表输出的查询。我确实在网上找到了一些返回动态交叉表结果的解决方案,但它只在单个级别返回。下面是SQL FIDLE: CREATE TABLE dbo.PopulationDetails ( Country VARCHAR(50), State VARCHAR(50), Population BIGINT, SeatsInHouse INT ) INSERT INTO PopulationDetails VALUES('United States','Ca
CREATE TABLE dbo.PopulationDetails
(
Country VARCHAR(50),
State VARCHAR(50),
Population BIGINT,
SeatsInHouse INT
)
INSERT INTO PopulationDetails
VALUES('United States','California', 38332521, 53),
('United States','Texas', 26448193, 36),
('United States','New York', 19651127, 27),
('United States','Florida', 19552860, 27),
('United States','Illinois', 12882135, 18)
我希望我的输出应该如下所示。状态的数量不是固定的,可能会根据需要而变化
United States
California Texas New York Florida Illinois
Population 38332521 26448193 19651127 19552860 12882135
SeatsInHouse 53 36 27 27 18
正如我在评论中所说,多级列标题不能通过SQL完成。您必须在表示层(如应用程序或SSR)中格式化数据。如果您想将
国家
和州
值“放在一起”,则必须将这些名称串联在一起,并将其作为新列名
如果您想在SQL中获得结果,我首先要连接国家
和州
,以及取消PIVOT
列人口
和SeatHouse
。此过程的基本语法为:
select
country_state = replace(pd.Country +'_'+pd.State, ' ', ''),
c.col,
c.value
from dbo.PopulationDetails pd
cross apply
(
values
('Population', pd.population),
('SeatsInHouse', pd.SeatsInHouse)
) c (col, value);
看。这就产生了一个结果:
| COUNTRY_STATE | COL | VALUE |
|-------------------------|--------------|----------|
| UnitedStates_California | Population | 38332521 |
| UnitedStates_California | SeatsInHouse | 53 |
| UnitedStates_Texas | Population | 26448193 |
| UnitedStates_Texas | SeatsInHouse | 36 |
| UnitedStates_NewYork | Population | 19651127 |
| UnitedStates_NewYork | SeatsInHouse | 27 |
| COL | UNITEDSTATES_CALIFORNIA | UNITEDSTATES_FLORIDA | UNITEDSTATES_ILLINOIS | UNITEDSTATES_NEWYORK | UNITEDSTATES_TEXAS |
|--------------|-------------------------|----------------------|-----------------------|----------------------|--------------------|
| Population | 38332521 | 19552860 | 12882135 | 19651127 | 26448193 |
| SeatsInHouse | 53 | 27 | 18 | 27 | 36 |
您将看到,现在每个Country\u State
组合有两行。现在,您可以将这些Country\u State
值透视到列中:
select col, UnitedStates_California, UnitedStates_Texas,
UnitedStates_NewYork, UnitedStates_Florida,
UnitedStates_Illinois
from
(
select
country_state = replace(pd.Country +'_'+pd.State, ' ', ''),
c.col,
c.value
from dbo.PopulationDetails pd
cross apply
(
values
('Population', pd.population),
('SeatsInHouse', pd.SeatsInHouse)
) c (col, value)
) d
pivot
(
max(value)
for country_state in (UnitedStates_California, UnitedStates_Texas,
UnitedStates_NewYork, UnitedStates_Florida,
UnitedStates_Illinois)
) piv;
看
现在,如果您需要动态地完成此操作,那么您必须使用动态SQL来创建一个字符串,然后执行该字符串
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(country_state)
from
(
select country_state = replace(Country +'_'+State, ' ', '')
from dbo.PopulationDetails
) d
group by country_state
order by country_state
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT col, ' + @cols + '
from
(
select
country_state = replace(pd.Country +''_''+pd.State, '' '', ''''),
c.col,
c.value
from dbo.PopulationDetails pd
cross apply
(
values
(''Population'', pd.population),
(''SeatsInHouse'', pd.SeatsInHouse)
) c (col, value)
) x
pivot
(
max(value)
for country_state in (' + @cols + ')
) p '
exec sp_executesql @query;
看。两者都给出了一个结果:
| COUNTRY_STATE | COL | VALUE |
|-------------------------|--------------|----------|
| UnitedStates_California | Population | 38332521 |
| UnitedStates_California | SeatsInHouse | 53 |
| UnitedStates_Texas | Population | 26448193 |
| UnitedStates_Texas | SeatsInHouse | 36 |
| UnitedStates_NewYork | Population | 19651127 |
| UnitedStates_NewYork | SeatsInHouse | 27 |
| COL | UNITEDSTATES_CALIFORNIA | UNITEDSTATES_FLORIDA | UNITEDSTATES_ILLINOIS | UNITEDSTATES_NEWYORK | UNITEDSTATES_TEXAS |
|--------------|-------------------------|----------------------|-----------------------|----------------------|--------------------|
| Population | 38332521 | 19552860 | 12882135 | 19651127 | 26448193 |
| SeatsInHouse | 53 | 27 | 18 | 27 | 36 |
通过SQL,您不可能真正获得这样的多级结果。你;我必须在像你的应用程序甚至SSR这样的表示层中进行。你能做的最多的事情就是让列名前面的国家类似于
美国(u California)
,等等