将字段名称显示为列,将字段值显示为sql server中的行

时间:2017-06-20 13:56:15

标签: sql-server

我的表格包含FieldName,Field Value

with Data

    forms_data_id   fk_forms_id formcount   fieldname   fieldvalue  createddate
1   1   0   State   Alabama 2017-06-20 10:35:07.300
2   1   0   City    ahmedabad   2017-06-20 10:35:07.317
3   1   0   Zip 380061  2017-06-20 10:35:07.333
4   1   0   Gender  Male    2017-06-20 10:35:07.347
5   1   0   Job Developer   2017-06-20 10:35:07.363
6   1   0   IsActive    0   2017-06-20 10:35:07.380
7   1   0   Lastname    1234    2017-06-20 10:35:07.393
8   1   0   Firstname   1234    2017-06-20 10:35:07.410

,  我想要结果

FirstName  LastName Gender
Ram         Mehta   Male
Shyam       Mehra   Male

但我的问题是字段名称不固定。我可以是5或10个。

我需要MSSQL查询来实现上面的结果

3 个答案:

答案 0 :(得分:0)

仍然不完全清楚你想要什么,但你可以使用交叉表(也就是条件聚合)来做这类事情。

请注意我如何发布您的样本数据,以便其他人可以随时使用。你应该在将来这样做,以便人们更容易帮助。

DECLARE @Something TABLE
(
    forms_data_id INT
    , fk_forms_id INT
    , formcount INT
    , fieldname VARCHAR(50)
    , fieldvalue VARCHAR(50)
    , createddate DATETIME
)

INSERT @Something
(
    forms_data_id,
    fk_forms_id,
    formcount,
    fieldname,
    fieldvalue,
    createddate
)
VALUES
(1, 1, 0, 'State', 'Alabama', '2017-06-20 10:35:07.300'), 
(2, 1, 0, 'City', 'ahmedabad', '2017-06-20 10:35:07.317'), 
(3, 1, 0, 'Zip', '380061', '2017-06-20 10:35:07.333'), 
(4, 1, 0, 'Gender', 'Male', '2017-06-20 10:35:07.347'), 
(5, 1, 0, 'Job', 'Developer', '2017-06-20 10:35:07.363'), 
(6, 1, 0, 'IsActive', '0', '2017-06-20 10:35:07.380'), 
(7, 1, 0, 'Lastname', '1234', '2017-06-20 10:35:07.393'), 
(8, 1, 0, 'Firstname', '1234', '2017-06-20 10:35:07.410')

SELECT MAX(CASE WHEN fieldname = 'Firstname' THEN fieldvalue END) AS FirstName
    , MAX(CASE WHEN fieldname = 'Lastname' THEN fieldvalue END) AS LastName
    , MAX(CASE WHEN fieldname = 'Gender' THEN fieldvalue END) AS Gender
FROM @Something s
GROUP BY s.fk_forms_id

这是解决这个问题的另一种方法。这是使用动态交叉表。我觉得这比动态支点更好,因为对我来说语法不那么钝。我首先必须从表变量切换到临时表。

IF OBJECT_ID('tempdb..#Something') IS NOT NULL
    DROP TABLE #Something
GO

CREATE table #Something
(
    forms_data_id INT
    , fk_forms_id INT
    , formcount INT
    , fieldname VARCHAR(50)
    , fieldvalue VARCHAR(50)
    , createddate DATETIME
)

INSERT #Something
(
    forms_data_id,
    fk_forms_id,
    formcount,
    fieldname,
    fieldvalue,
    createddate
)
VALUES
(1, 1, 0, 'State', 'Alabama', '2017-06-20 10:35:07.300'), 
(2, 1, 0, 'City', 'ahmedabad', '2017-06-20 10:35:07.317'), 
(3, 1, 0, 'Zip', '380061', '2017-06-20 10:35:07.333'), 
(4, 1, 0, 'Gender', 'Male', '2017-06-20 10:35:07.347'), 
(5, 1, 0, 'Job', 'Developer', '2017-06-20 10:35:07.363'), 
(6, 1, 0, 'IsActive', '0', '2017-06-20 10:35:07.380'), 
(7, 1, 0, 'Lastname', '1234', '2017-06-20 10:35:07.393'), 
(8, 1, 0, 'Firstname', '1234', '2017-06-20 10:35:07.410')

现在有了一个临时表,我们可以稍微改变一下。

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as
    (
        select *, ROW_NUMBER() over(partition by fk_forms_id order by fieldname) as RowNum
        from #Something
    )
    select fk_forms_id';

declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by fk_forms_id order by fk_forms_id';

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then fieldvalue end) as ' + Cols.fieldname --+ CAST(N as varchar(6)) + CHAR(10)
from cteTally t
JOIN
(
    SELECT DISTINCT fieldname
        , forms_data_id
    FROM #Something s
) Cols ON Cols.forms_data_id = t.N
where t.N <= 
(
    select top 1 Count(*)
    from #Something
    group by fk_forms_id
    order by COUNT(*) desc
)

select @StaticPortion + @DynamicPortion + @FinalStaticPortion

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
exec sp_executesql @SqlToExecute

答案 1 :(得分:0)

你可以用它。它会对你有用。

CREATE VIEW [dbo].[VIEW_YOURTABLE] AS
SELECT 
FieldName
,FieldValue
,ROW_NUMBER() OVER(PARTITION BY FieldName ORDER BY FieldValue ASC) AS RN
FROM YOUR_TABLE

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', ' + QUOTENAME(FieldName)
  FROM 
  (
    SELECT DISTINCT FieldName FROM VIEW_YOURTABLE
  ) AS x;
SET @sql = N'SELECT ' 
+ STUFF(@columns, 1, 2, '') 
+ 'FROM
(

SELECT RN, FieldName, FieldValue FROM VIEW_YOURTABLE

) AS j PIVOT
(
  MAX(FieldValue) FOR FieldName IN ('
  + STUFF(REPLACE(@columns, ', [', ',['), 1, 1, '')
  + ')
) AS p ORDER BY p.RN;';
EXEC sp_executesql @sql;

答案 2 :(得分:0)

您可以使用交叉表生成此类结果。

假设你有一个像这样的表:

姓名薪水
马克3000
大卫4000
Kyal 15000
Jhon 10000

然后下面的查询可以生成如下所示的结果:

选择[马克],[大卫],[Kyal],[Jhon]
来自 (选择姓名,薪水
    来自EmpSalary)AS MainTable
PIVOT

SUM(薪水)
FOR Name In([Mark],[David],[Kyal],[Jhon])
)AS PT;

输出:

Mark David Kyal Jhon 3000 4000 15000 10000

希望这是你想要达到的目标。

的Manoj。