Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 多级交叉表动态查询_Sql_Sql Server 2008_Tsql_Pivot - Fatal编程技术网

Sql 多级交叉表动态查询

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

我试图找到一个可以在多个级别动态生成交叉表输出的查询。我确实在网上找到了一些返回动态交叉表结果的解决方案,但它只在单个级别返回。下面是SQL FIDLE:

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)
,等等