简体   繁体   English

循环创建新列

[英]Loop to create new columns

Say that I have a SQL Server table which has 4 columns MonthEnd , Gender , Weight and Age .假设我有一个 SQL 服务器表,它有 4 列MonthEndGenderWeightAge

Now, the MonthEnd go from 201901 through 201912.现在,从MonthEnd到 201912 的 MonthEnd go。

I have a process where a run a query which generates a variety of metrics, for instance sum(Weight) and average(Age) for each month.我有一个过程,其中运行一个生成各种指标的查询,例如每个月的总和(体重)和平均(年龄)。

Right now, I set a where MonthEnd = 201901 when I create the metrics for that month.现在,我在创建该月的指标时设置了where MonthEnd = 201901

The output is a table with 2 columns and 2 rows. output 是一个 2 列 2 行的表。 The Column1 header is Metric and the Column2 header is 201901 and then row1 column1 says Total_Weight and row1 column2 is the value generated by the sum(weight) function. Column1 header 是公制,Column2 header 是 201901 然后 row1 column1 表示 Total_Weight 和 row1 column2 是总和(重量)ZC1C425268E617A94D 生成的值 ZC1C425268E617A94D

Similarly, row2 column1 says Average_Age and row2 column2 is the result of the Average(Age) function.同样,row2 column1 表示 Average_Age,row2 column2 是 Average(Age) function 的结果。

I have the above done.我已经完成了上述工作。

Then, I have to rerun the code after changing the where clause to where MonthEnd = 201902 and then the same structure applies to results.然后,我必须在将 where 子句更改为 where MonthEnd = 201902 后重新运行代码,然后将相同的结构应用于结果。

I want to be able to run 201901 through 201912 in one step and have the output reflect 13 columns, namely, column1 would still be the metric with a header “Metric” but the next 12 columns would have headers 201901 through 201912 with the corresponding results for each month included below the headers.我希望能够一步运行 201901 到 201912 并让 output 反映 13 列,即 column1 仍将是具有 Z099FB995346F31C749F6E40DB0F31C749F6E40DB0F395E3Z “Metric”的度量标准,但接下来的 12 列将具有 019120 对应的标题到 20包含在标题下方的每个月。

Can T-SQL do this? T-SQL 可以做到这一点吗? I feel like I can do it with 1 aggregation function using Pivot but I haven't figured out how to do multiple aggregate functions at the same time.我觉得我可以使用 Pivot 使用 1 个聚合 function 来做到这一点,但我还没有弄清楚如何同时执行多个聚合函数。

-- THIS SECTION SETS UP THE DATA SET STARTING POINT ---------

IF OBJECT_ID('[dbo].[example]') IS NOT NULL DROP TABLE [dbo].[example]
GO

CREATE TABLE [dbo].[example]
(
MonthEnd INT NOT NULL,
Grade VARCHAR(50) NOT NULL,
Name VARCHAR(50) NOT NULL,
Amount INT NULL
)
GO

INSERT INTO [dbo].[example]
VALUES 
(201901, 'A', 'Josh', 100),
(201901, 'A', 'Joe', 50),
(201901, 'A', 'Jill', 150),
(201901, 'B', 'Julie', 150),
(201901, 'B', 'Jim', 350),
(201901, 'C', 'Jeff', 100),
(201901, 'C', 'Jack', 125),
(201901, 'C', 'Jillian', 150),
(201901, 'C', 'Jess', 175),
(201901, 'C', 'James', 450),
(201902, 'A', 'Josh', 95),
(201902, 'A', 'Jill', 105),
(201902, 'B', 'Julie', 125),
(201902, 'B', 'Jim', 325),
(201902, 'C', 'Jeff', 75),
(201902, 'C', 'Jack', 100),
(201902, 'C', 'Jillian', 125),
(201903, 'A', 'Josh', 50),
(201903, 'B', 'Julie', 75),
(201903, 'B', 'Jim', 300),
(201903, 'C', 'Jeff', 50),
(201903, 'C', 'Jack', 50);

select * from [dbo].[example]

-- THE BELOW SECTION GENERATES THE DESIRED RESULTS WHICH I'D LIKE TO ACHIEVE THROUGH A PIVOT OR LOOP ---
-- I HAVE MONTHS FROM 201801 through 202103, SO I'D LIKE TO ITERATE THROUGH THEM AND PRODUCE THE DESIRED RESULT SET PROGRAMMATICALLY ---

IF OBJECT_ID('tempdb..#temp1') IS NOT NULL drop table #temp1
IF OBJECT_ID('tempdb..#temp2') IS NOT NULL drop table #temp2
IF OBJECT_ID('tempdb..#temp3') IS NOT NULL drop table #temp3

select 
    cast(Grade as varchar(max)) as Grade
    ,cast(Name as varchar(max)) as Name
    ,'SUM' as Metric
    ,cast(sum(Amount) as varchar(max)) as '201901'
into #temp1
from [dbo].[example] 
where MonthEnd = '201901'
group by 
    cast(Grade as varchar(max))
    ,cast(Name as varchar(max))

    union all

select 
    cast(Grade as varchar(max)) as Grade
    ,cast(Name as varchar(max)) as Name
    ,'AVG' as Metric
    ,cast(avg(Amount) as varchar(max)) as '201901'
from [dbo].[example] 
where MonthEnd = '201901'
group by 
    cast(Grade as varchar(max))
    ,cast(Name as varchar(max))


select 
    cast(Grade as varchar(max)) as Grade
    ,cast(Name as varchar(max)) as Name
    ,'SUM' as Metric
    ,cast(sum(Amount) as varchar(max)) as '201902'
into #temp2
from [dbo].[example] 
where MonthEnd = '201902'
group by 
    cast(Grade as varchar(max))
    ,cast(Name as varchar(max))

    union all

select 
    cast(Grade as varchar(max)) as Grade
    ,cast(Name as varchar(max)) as Name
    ,'AVG' as Metric
    ,cast(avg(Amount) as varchar(max)) as '201902'
from [dbo].[example] 
where MonthEnd = '201902'
group by 
    cast(Grade as varchar(max))
    ,cast(Name as varchar(max))


select 
    cast(Grade as varchar(max)) as Grade
    ,cast(Name as varchar(max)) as Name
    ,'SUM' as Metric
    ,cast(sum(Amount) as varchar(max)) as '201903'
into #temp3
from [dbo].[example] 
where MonthEnd = '201903'
group by 
    cast(Grade as varchar(max))
    ,cast(Name as varchar(max))

    union all

select 
    cast(Grade as varchar(max)) as Grade
    ,cast(Name as varchar(max)) as Name
    ,'AVG' as Metric
    ,cast(avg(Amount) as varchar(max)) as '201903'
from [dbo].[example] 
where MonthEnd = '201903'
group by 
    cast(Grade as varchar(max))
    ,cast(Name as varchar(max))

select 
    a.Grade
    ,a.Name
    ,a.Metric
    ,a.[201901]
    ,b.[201902]
    ,c.[201903]
from #temp1 a
left join #temp2 b
on  a.Grade = b.Grade and a.Name = b.Name and a.Metric = b.Metric
left join #temp3 c
on  a.Grade = c.Grade and a.Name = c.Name and a.Metric = c.Metric

The output is a table with 2 columns and 2 rows. output 是一个 2 列 2 行的表。 The Column1 header is Metric and the Column2 header is 201901 and then row1 column1 says Total_Weight and row1 column2 is the value generated by the sum(weight) function. Column1 header 是公制,Column2 header 是 201901 然后 row1 column1 表示 Total_Weight 和 row1 column2 是总和(重量)ZC1C425268E617A94D 生成的值 ZC1C425268E617A94D

You've got that backwards.你搞反了。 Make each metric a seperate column and have a seperate row for each Month, and Gender.将每个指标设为单独的列,并为每个月和性别设置单独的行。

(Month, Gender, AverageAge, TotalWeight, . . .) (月、性别、平均年龄、总体重……)

If you need the data displayed differently, worry about that in the front-end, or use TSQL PIVOT after you build the resultset.如果您需要以不同方式显示的数据,请在前端担心,或者在构建结果集后使用 TSQL PIVOT。

I was able to use pivot approach to generate the desired result我能够使用 pivot 方法来生成所需的结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM