2017-06-14 54 views
0

我在SQL Server 2012中有一个数据库表“table_name1”,以显示在一个单一的列值划分为多个和组创建的使用:如何通过另一列

CREATE TABLE table_name1 (
    created_date date, 
    complete_hour int, 
    col_percent float 
); 

INSERT INTO table_name1 values 
('2017-06-14', 8, 0.3), 
('2017-06-14', 9, 1.96), 
('2017-06-14', 10, 3.92), 
('2017-06-07', 8, 0.17), 
('2017-06-07', 9, 2.87), 
('2017-06-07', 10, 3.72), 
('2017-05-31', 7, 0.14), 
('2017-05-31', 8, 0.72), 
('2017-05-31', 9, 3.77), 
('2017-05-31', 10, 5.8); 

我想要做的就是结果,如:

created_date col1 col2 col3 col4 
2017-06-14  BLANK 0.3  1.96 3.92 
2017-06-07  BLANK 0.17 2.87 3.72 
2017-05-31  0.14 0.72 3.77 5.8 

我尝试使用支点和在table_name1行数会不断变化,我想我将不得不使用动态SQL。所以我尝试使用Efficiently convert rows to columns in sql server后的回答,但无法调整它来解决我的问题。有3列,而不是两个,我需要考虑,也必须由created_date分组。

我可以得到一些关于如何做到这一点的建议吗?

编辑:答案我想跟随的小修改后的版本是:

DECLARE @cols AS NVARCHAR(MAX), 
     @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(col_percent) 
        from table_name1 
        group by created_date, complete_hour, col_percent 
        order by complete_hour 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = N'SELECT ' + @cols + N' from 
      (
       select created_date, col_percent 
       from table_name1     
      ) x 
      pivot 
      (
       max(created_date) 
       for col_percent in (' + @cols + N') 
      ) p ' 

exec sp_executesql @query; 

,并让结果为:

0.14  0.72  0.17  0.3   3.77  2.87  1.96  5.8   3.72  3.92 
2017-05-31 2017-05-31 2017-06-07 2017-06-14 2017-05-31 2017-06-07 2017-06-14 2017-05-31 2017-06-07 2017-06-14 

我知道我做错了,让我的期望输出,但是当我尝试更改数据透视表中的列名称时,我得到了一些其他更改,或者在“PIVOT”运算符中提供了“无效列名”或“不正确的值”0.14“。

+0

你能告诉我们你的,你提到的答案的版本?为什么它不符合你想要的输出? – SchmitzIT

+0

我编辑过的问题包括我试图调整的SQL版本,以便提供所需的结果。我不认为我理解它100%,但试图。 – 300

回答

1

如果我们拿东西,在一步一个脚印,让我们试着和第一做到这一点,而无需使用动态SQL。

我相信这个查询产生你正在寻找的结果:

SELECT created_date, [7] AS col1, [8] AS col2, [9] AS col3, [10] AS col4 
FROM 
    (
     select created_date, complete_hour, col_percent 
     from table_name1     
    ) x 
    pivot 
    (
     max(col_percent) 
     for complete_hour in ([7],[8],[9],[10]) 
    ) p 
    ORDER BY created_date DESC 

输出:

created_date col1 col2 col3 col4 
2017-06-14  NULL 0,3  1,96 3,92 
2017-06-07  NULL 0,17 2,87 3,72 
2017-05-31  0,14 0,72 3,77 5,8 

****更新:OP确认的结果看起来是正确的。现在,对于一些动态SQL忍者东西

为了使这更动态一点,下面的工作:

我们开始通过声明两个变量,将持有的列和查询:

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) 

接下来,我们确定我们想从表中获取的列。在我们的案例中,这是complete_hour。看到这些最有可能重复了好几天了,我们只希望他们一次,我们GROUP BY complete_hour

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(complete_hour) 
        from table_name1 
        group by complete_hour 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

现在,我们可以测试什么是我们的变量:根据所提供的测试数据

PRINT @cols 

,目前它将包含

[7],[8],[9],[10] 

在现实生活中,这将是每个独特的complete_hour值的值。

在-病房与构建查询:

set @query = N'SELECT created_date, ' + @cols + N' from 
      (
       select created_date, complete_hour, col_percent 
       from table_name1     
      ) x 
      pivot 
      (
       max(col_percent) 
       for complete_hour in (' + @cols + N') 
      ) p 
      ORDER BY created_date DESC 
     ' 

正如你想要的CREATED_DATE列,需要在SELECT语句。我们还希望complete_hour的每个值都是我们存储在@cols中的值。

我们实际上想抓住一切,所以我们选择所有三列,然后为每个complete_hour转动col_percent。

最后,我们排序created_date,最新的日期显示第一。

我们就可以执行:

exec sp_executesql @query; 
+0

是的,这适用于现有的样品台。 – 300

+0

@ 300太棒了。那么我是否认为你需要更多的列呢?命名它们可能会有些棘手,但我们可以试试它。但是,上面的查询可以用作创建您之后的动态SQL的基础。 – SchmitzIT

+0

是的,我需要更多的列,但是他们会在6到23之间。但是我不知道将出现在table_name1中的行数 – 300

1

你可以做一个动态的关键点来获得你想要的。下面是一个使用临时表从你的例子为例:

CREATE TABLE #table_name1 (
    created_date date, 
    complete_hour int, 
    col_percent float 
); 

INSERT INTO #table_name1 values 
('2017-06-14', 8, 0.3), 
('2017-06-14', 9, 1.96), 
('2017-06-14', 10, 3.92), 
('2017-06-07', 8, 0.17), 
('2017-06-07', 9, 2.87), 
('2017-06-07', 10, 3.72), 
('2017-05-31', 7, 0.14), 
('2017-05-31', 8, 0.72), 
('2017-05-31', 9, 3.77), 
('2017-05-31', 10, 5.8); 


declare @sql nvarchar(max), 
     @pvtColumns nvarchar(max), 
     @selectColumns nvarchar(max) 

select @pvtColumns = (
         select ''+PivotColumns+',' 
         from (
          select distinct 
            '['+convert(Varchar(10), complete_hour)+']' as PivotColumns, complete_hour 
          from #table_name1 
          ) as b 
         order by complete_hour 
         for xml path('') 
        ) 

select @pvtColumns = substring(@pvtColumns,1,len(@pvtColumns)-1) 


set @sql = 

' 
select 
    p.created_date, 
    '[email protected]+' 
from   
    (
    select 
     created_date, 
     complete_hour, 
     col_percent 
    from #table_name1 
    ) 
    as main 
    pivot 
    (
     max(col_percent) 
     for complete_hour in ('[email protected]+') 
    ) as p 
order by 
    created_date 
' 

exec sp_Executesql @sql 
+0

谢谢你的回应杰西。我希望我可以将多个答复标记为答案。您的解决方案对我来说也很完美,但除了SchmitzIT之外,我无法将其标记为答案。我对此表示歉意。 – 300

+0

所有的好,很高兴你有你需要的。 – Jesse