TSQL表变换字段=>列(TSQL Table Transformation Fields =

2019-09-29 01:07发布

我有以下表格布局。 每一行的值将始终是唯一的。 永远不会有相同的ID,名称,和线多个实例。

Id Name Line
1  A    Z
2  B    Y
3  C    X
3  C    W
4  D    W

我想查询数据以使该行字段变为一列。 如果该值存在,一个1在现场数据施加,否则为0。例如

Id Name Z Y X W
1  A    1 0 0 0
2  B    0 1 0 0
3  C    0 0 1 1
4  D    0 0 0 1

字段名W,X,Y,Z都只是字段值的例子,所以我不能申请一个运营商明确检查,例如,“X”,“Y”,或“Z”。 这些随时都可能发生变化,并不局限于一finate组值。 在结果集的列名应体现出独特的字段值列。

任何想法,我怎么能做到这一点?

Answer 1:

这是一个标准的支点查询。

如果1代表一个布尔值指标 - 使用:

  SELECT t.id,
         t.name,
         MAX(CASE WHEN t.line = 'Z' THEN 1 ELSE 0 END) AS Z,
         MAX(CASE WHEN t.line = 'Y' THEN 1 ELSE 0 END) AS Y,
         MAX(CASE WHEN t.line = 'X' THEN 1 ELSE 0 END) AS X,
         MAX(CASE WHEN t.line = 'W' THEN 1 ELSE 0 END) AS W
    FROM TABLE t
GROUP BY t.id, t.name

如果1代表与该组值的记录数,使用:

  SELECT t.id,
         t.name,
         SUM(CASE WHEN t.line = 'Z' THEN 1 ELSE 0 END) AS Z,
         SUM(CASE WHEN t.line = 'Y' THEN 1 ELSE 0 END) AS Y,
         SUM(CASE WHEN t.line = 'X' THEN 1 ELSE 0 END) AS X,
         SUM(CASE WHEN t.line = 'W' THEN 1 ELSE 0 END) AS W
    FROM TABLE t
GROUP BY t.id, t.name


Answer 2:

有关编辑下面的更新

SQL Server不支持动态旋转。

要做到这一点,你既可以使用动态SQL生成大意如下的查询。

SELECT 
       Id ,Name, 
       ISNULL(MAX(CASE WHEN Line='Z' THEN 1 END),0) AS Z,
       ISNULL(MAX(CASE WHEN Line='Y' THEN 1 END),0) AS Y,
       ISNULL(MAX(CASE WHEN Line='X' THEN 1 END),0) AS X,
       ISNULL(MAX(CASE WHEN Line='W' THEN 1 END),0) AS W
FROM T
 GROUP BY Id ,Name

或者我看过但实际上没有尝试过的另一种方法是利用访问Transform通过一个链接表在SQL Server表指向然后查询从SQL Server Access数据库设置Access数据库的功能!



Answer 3:

这里是动态版本

测试表

create table #test(id int,name char(1),line char(1))

insert #test values(1 , 'A','Z')
insert #test values(2 , 'B','Y')
insert #test values(3 , 'C','X')
insert #test values(4 , 'C','W')
insert #test values(5 , 'D','W')
insert #test values(5 , 'D','W')
insert #test values(5 , 'D','P')

现在运行这个

declare @names nvarchar(4000)

SELECT @names =''
  SELECT  @names    = @names +   line +', '  
    FROM (SELECT distinct  line from #test) x

SELECT @names = LEFT(@names,(LEN(@names) -1))

exec('
SELECT *
 FROM(
SELECT DISTINCT Id, Name,Line
FROM #test
    ) AS pivTemp
PIVOT
(   COUNT(Line)
    FOR Line IN (' + @names +' )
) AS pivTable ')

现在添加一行到表及以上再次运行查询,你会看到在B

insert #test values(5 , 'D','B')

注意 :当然,所有的动态SQL的问题适用,如果你可以使用sp_executesql的,但由于参数不查询一样使用真的是没有一点



Answer 4:

假设你有,你可以列举线值的数量有限:

declare @MyTable table (
    Id int,
    Name char(1),
    Line char(1)
)

insert into @MyTable
    (Id, Name, Line)
    select 1,'A','Z'
    union all
    select 2,'B','Y'
    union all
    select 3,'C','X'
    union all
    select 3,'C','W'
    union all
    select 4,'D','W'

SELECT Id, Name, Z, Y, X, W
    FROM (SELECT Id, Name, Line
            FROM @MyTable) up
    PIVOT (count(Line) FOR Line IN (Z, Y, X, W)) AS pvt
    ORDER BY Id


Answer 5:

当你正在使用SQL Server,你可能使用PIVOT用于这一目的操作。



Answer 6:

如果你这样做了SQL Server报表服务(SSRS)报告,或可能可能转而使用一个,那么现在走走停停抛出一个矩阵控制到您的报告。 噗! 你完成了! 快乐与您的数据蛤蜊转动。



Answer 7:

这是一个颇为奇特的方法(使用旧Northwind数据库样本数据)。 它改编自版本在这里 ,不再因DBCC RENAMECOLUMN的折旧和增加PIVOT作为关键字的工作。

set nocount on 
create table Sales ( 
  AccountCode char(5), 
  Category varchar(10), 
  Amount decimal(8,2) 
) 
--Populate table with sample data 
insert into Sales 
select customerID, 'Emp'+CAST(EmployeeID as char), sum(Freight) 
from Northwind.dbo.orders 
group by customerID, EmployeeID 
create unique clustered index Sales_AC_C 
on Sales(AccountCode,Category) 
--Create table to hold data column names and positions 
select A.Category, 
       count(distinct B.Category) AS Position 
into #columns 
from Sales A join Sales B 
on A.Category >= B.Category 
group by A.Category 
create unique clustered index #columns_P on #columns(Position) 
create unique index #columns_C on #columns(Category) 
--Generate first column of Pivot table 
select distinct AccountCode into Pivoted from Sales 
--Find number of data columns to be added to Pivoted table 
declare @datacols int 
select @datacols = max(Position) from #columns 
--Add data columns one by one in the correct order 
declare @i int 
set @i = 0 
while @i < @datacols begin 
  set @i = @i + 1 
--Add next data column to Pivoted table 
  select P.*, isnull(( 
    select Amount 
    from Sales S join #columns C 
    on C.Position = @i 
    and C.Category = S.Category 
    where P.AccountCode = S.AccountCode),0) AS X 
  into PivotedAugmented 
  from Pivoted P 
--Name new data column correctly 
  declare @c sysname 
  select @c = Category 
  from #columns 
  where Position = @i 
  exec sp_rename '[dbo].[PivotedAugmented].[X]', @c, 'COLUMN'
--Replace Pivoted table with new table 
  drop table Pivoted 
  select * into Pivoted from PivotedAugmented 
  drop table PivotedAugmented 
end 
select * from Pivoted 
go 
drop table Pivoted 
drop table #columns 
drop table Sales 


文章来源: TSQL Table Transformation Fields => Columns