Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/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 2005 - Fatal编程技术网

使用动态sql数据透视两列

使用动态sql数据透视两列,sql,sql-server-2005,Sql,Sql Server 2005,我正试着把两匹驴转成一排 NO Code Amount -- ---- ------- 1 61 1714.00 1 23 95.79 1 80 31.00 1 61 45.00 2 61 1714.00 2 23 95.79 3 80 31.00 4 61 45.00 4 61 1714.00 4 23 95.79 4 80 31.00 4 61 45.00 我希望动态地将代码和金额列转换为如下所示,并为列名添加后缀 N

我正试着把两匹驴转成一排

NO Code Amount
-- ---- -------
1  61   1714.00
1  23   95.79
1  80   31.00
1  61   45.00
2  61   1714.00
2  23   95.79
3  80   31.00
4  61   45.00
4  61   1714.00
4  23   95.79
4  80   31.00
4  61   45.00
我希望动态地将代码和金额列转换为如下所示,并为列名添加后缀

NO Code_01 Amount_01 Code_02 Amount_02 Code_03 Amount_03 Code_04 Amount_04
1  61      1714.00   23      95.79     80      31.00     61      45.00
2  61      1714.00   23      95.79     - - - - 
...
我开始写一篇专栏文章,但遇到了错误……有什么帮助吗

DECLARE @cols NVARCHAR(MAX)
    ,@sql NVARCHAR(MAX)

SET @cols = STUFF((
            SELECT DISTINCT ',' + QUOTENAME(CODE)
            FROM Table1
            ORDER BY 1
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET @sql = 'SELECT NO,  ' + @cols + '
              FROM
            (
              SELECT NO
                FROM Table1
            ) s
            PIVOT
            (
              MAX(Amount) FOR Code IN (' + @cols + ')
            ) p'

--print(@sql)

EXECUTE(@sql)

使用动态sql生成条件聚合语句以获取
max()
by(按
No
分区),而不是多个数据透视:

declare @cols nvarchar(max);
declare @sql  nvarchar(max);
select @cols = stuff((
    select distinct 
      char(10)+'  , ' 
      + quotename('Code_'+rn)+'   = max(case when rn = '+rn+' then Code end)'
      + char(10)+'  , ' 
      + quotename('Amount_'+rn)+' = max(case when rn = '+rn+' then Amount end)'
    from (
      select No, Code
        , rn = convert(varchar(10),row_number() over (partition by No order by Code))
      from Table1 
      ) s
    order by 1
    for xml path (''), type).value('.','nvarchar(max)')
  ,1,0,'');

select  @sql ='
select No '+@cols+'
from (
  select No, Code, Amount
    , rn = row_number() over (partition by No order by Code) 
  from Table1 
  ) sub
group by No';

select @sql;
exec(@sql);
rextester演示:

生成的代码:

select No 
  , [Code_1]   = max(case when rn = 1 then Code end)
  , [Amount_1] = max(case when rn = 1 then Amount end)
  , [Code_2]   = max(case when rn = 2 then Code end)
  , [Amount_2] = max(case when rn = 2 then Amount end)
  , [Code_3]   = max(case when rn = 3 then Code end)
  , [Amount_3] = max(case when rn = 3 then Amount end)
  , [Code_4]   = max(case when rn = 4 then Code end)
  , [Amount_4] = max(case when rn = 4 then Amount end)
  , [Code_5]   = max(case when rn = 5 then Code end)
  , [Amount_5] = max(case when rn = 5 then Amount end)
from (
  select No, Code, Amount
    , rn = row_number() over (partition by No order by Code) 
  from Table1 
  ) sub
group by No
结果:

+----+--------+----------+--------+----------+--------+----------+--------+----------+--------+----------+
| No | Code_1 | Amount_1 | Code_2 | Amount_2 | Code_3 | Amount_3 | Code_4 | Amount_4 | Code_5 | Amount_5 |
+----+--------+----------+--------+----------+--------+----------+--------+----------+--------+----------+
|  1 |     23 | 95.79    | 61     | 45.00    | 61     | 1714.00  | 80     | 31.00    | NULL   | NULL     |
|  2 |     23 | 95.79    | 61     | 1714.00  | NULL   | NULL     | NULL   | NULL     | NULL   | NULL     |
|  3 |     80 | 31.00    | NULL   | NULL     | NULL   | NULL     | NULL   | NULL     | NULL   | NULL     |
|  4 |     23 | 95.79    | 61     | 45.00    | 61     | 45.00    | 61     | 1714.00  | 80     | 31.00    |
+----+--------+----------+--------+----------+--------+----------+--------+----------+--------+----------+

您可以像这样动态创建
PIVOT
查询

DECLARE @ColumnNames NVARCHAR(MAX) =''
SELECT  @ColumnNames = @ColumnNames + ', ' + QUOTENAME ( 'Code_' +  RN ) + ', ' + QUOTENAME ( 'Amount_' + RN  )  
FROM (SELECT DISTINCT RN = RIGHT('0' + CONVERT(varchar, ROW_NUMBER() OVER(PARTITION BY [NO] ORDER BY [NO]) ),2) FROM Table1 ) AS T
SET @ColumnNames = STUFF(@ColumnNames,1,1,'')


DECLARE @SqlText NVARCHAR(MAX)
SET @SqlText  = 'SELECT * FROM 
                    (SELECT [NO], ''Code_'' + RIGHT(''0'' + CONVERT(varchar, ROW_NUMBER() OVER(PARTITION BY [NO] ORDER BY [NO]) ),2) Col, CONVERT(VARCHAR,Code) Value FROM Table1
                       UNION ALL
                    SELECT  [NO], ''Amount_'' + RIGHT(''0'' + CONVERT(varchar, ROW_NUMBER() OVER(PARTITION BY [NO] ORDER BY [NO]) ),2) Col, CONVERT(VARCHAR,Amount) Value FROM Table1 ) SRC
                    PIVOT (MAX(Value) FOR Col IN (' + @ColumnNames + ') ) PVT'

print @SqlText
EXEC sp_executesql @SqlText
生成的查询:

SELECT * FROM 
(SELECT [NO], 'Code_' + RIGHT('0' + CONVERT(varchar, ROW_NUMBER() OVER(PARTITION BY [NO] ORDER BY [NO]) ),2) Col, CONVERT(VARCHAR,Code) Value FROM Table1
    UNION ALL
SELECT  [NO], 'Amount_' + RIGHT('0' + CONVERT(varchar, ROW_NUMBER() OVER(PARTITION BY [NO] ORDER BY [NO]) ),2) Col, CONVERT(VARCHAR,Amount) Value FROM Table1 ) SRC
PIVOT (MAX(Value) FOR Col IN ( [Code_01], [Amount_01], [Code_02], [Amount_02], [Code_03], [Amount_03], [Code_04], [Amount_04], [Code_05], [Amount_05]) ) PVT
结果:

NO  Code_01  Amount_01  Code_02  Amount_02  Code_03  Amount_03  Code_04  Amount_04  Code_05  Amount_05 
--- -------  ---------  -------  ---------  -------  ---------  -------  ---------  -------  ---------
1   61       1714.00    23       95.79      80       31.00      61       45.00      NULL     NULL
2   61       1714.00    23       95.79      NULL     NULL       NULL     NULL       NULL     NULL
3   80       31.00      NULL     NULL       NULL     NULL       NULL     NULL       NULL     NULL
4   61       45.00      61       1714.00    23       95.79      80       31.00      61       45.00

SqlZim-你有没有一个应用程序可以格式化你的结果集,这样你就可以把它发布到网上?