Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.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 - Fatal编程技术网

如何在SQL中创建名称-值对表

如何在SQL中创建名称-值对表,sql,Sql,使用SQL,如何转换这样的单行表 Firstname Surname Address1 City Country --------- ------- --------------- ------ ------- Bob Smith 101 High Street London UK …到一个包含名称-值对的表,如下所示: Name Value --------- ------- Firstname Bob Surname Smith Ad

使用SQL,如何转换这样的单行表

Firstname Surname Address1        City   Country
--------- ------- --------------- ------ -------
Bob       Smith   101 High Street London UK
…到一个包含名称-值对的表,如下所示:

Name      Value
--------- -------
Firstname   Bob
Surname     Smith
Address1    101 High Street
City        London
Country     UK
此脚本将创建原始表:

create table #OriginalTable (Firstname varchar(10), Surname varchar(10), 
Address1 varchar(50), City varchar(10), Country varchar(10))
insert into #OriginalTable 
select 
'Bob' Firstname, 
'Smith' Surname, 
'101 High Street' Address1, 
'London' City, 
'UK' Country
我想要的是一个通用解决方案,它不依赖于列名称始终与示例中的列名称相同

编辑: 我正在使用SQLServer2005。 我想要的解决方案是使用SQL脚本将这些数据转换为名称-值对表

答复: 使用我接受的答案,这就是我使用的:

select   
result.Name, 
result.Value    
from   
  (select
    convert(sql_variant,FirstName) AS FirstName,
    convert(sql_variant,Surname) AS Surname,
    convert(sql_variant,Address1) AS Address1,
    convert(sql_variant,City) AS City,
    convert(sql_variant,Country) AS Country
    from #OriginalTable) OriginalTable
  UNPIVOT (Value For Name In (Firstname, Surname, Address1, City, Country)) as result

这听起来像是自2005年以来PIVOT子句可以做的事情(查看第一个示例),但是您没有提到您使用的是哪种数据库引擎。

这不是一个完整的解决方案,而是一个头脑风暴的想法,如果您将信息与表中的schema.columns交叉连接会怎么样

SELECT column_name, OriginalTable.*
FROM information_schema.columns 
CROSS JOIN OriginalTable
WHERE table_name = 'OriginalTable'
AND /* PRIMARY KEY FILTER HERE*/

通常,使用应用程序代码在应用程序中进行透视是最有效的。数据透视并不是数据库的强项。

使用两个表。一个表作为“键”表,主表包含键表的id和值


然后,您可以向主表中添加
client\u id
之类的内容,并在
client\u id
key\u id
上设置一个唯一的键。基本上,您有两个问题-要
UNPIVOT
,数据类型必须一致。另一个问题是列数未知。您希望达到以下形式:

WITH    conformed
      AS ( SELECT   CONVERT(VARCHAR(255), [Firstname]) AS [Firstname],
                    CONVERT(VARCHAR(255), [Surname]) AS [Surname],
                    CONVERT(VARCHAR(255), [Address1]) AS [Address1],
                    CONVERT(VARCHAR(255), [City]) AS [City],
                    CONVERT(VARCHAR(255), [Country]) AS [Country]
           FROM     so1526080
         )
SELECT  ColumnKey,
        ColumnValue
FROM    conformed UNPIVOT ( ColumnValue FOR ColumnKey IN ( [Firstname], [Surname], [Address1], [City], [Country] ) ) AS unpvt
因此,使用使用元数据的动态SQL PIVOT(您可能需要使用TABLE_SCHEMA等来解决这个问题):


这是使用JSON的MS SQL Server解决方案。您不需要指定列名和数据类型。您只需在第3行指定表名和有效的where条件

DECLARE @TEMP TABLE (JSONHOLDER NVARCHAR(MAX));
INSERT INTO @TEMP
SELECT (SELECT * FROM YOURTABLE WHERE YOURID = 2589 FOR JSON AUTO) AS JSONHOLDER
SELECT [KEY] as ColumnName, [VALUE] as ColumnValue FROM (SELECT [KEY] AS OLDKEY, [VALUE] AS OLDVALUE  FROM @TEMP A
CROSS APPLY OPENJSON(A.JSONHOLDER)) B CROSS APPLY OPENJSON(B.OLDVALUE)

您使用的是什么数据库管理系统?不同的数据库管理系统以不同的方式存储列的名称,所以每个键都有多行?e、 g.如果原始表中不仅有Bob Smith的一行,还有John Doe的一行,那么您的名称-值对表中的每个键将有2行。请参阅类似问题的答案:@Dominic。否,原始表将始终只有一行。如果数据库中有更多的行供不同的人使用,那么原始表仍然只有一行,b/c它只是一个人的过滤器。您可以使用UNPIVOT进行操作。我读了这个问题,然后发现这个:。我会尝试一下。我不认为你可以在不知道字段名的情况下进行透视。但是如果可以,请发布SQLServer。对不起,我自己不使用SQL Server,只在Microsoft文档中阅读。
DECLARE @TEMP TABLE (JSONHOLDER NVARCHAR(MAX));
INSERT INTO @TEMP
SELECT (SELECT * FROM YOURTABLE WHERE YOURID = 2589 FOR JSON AUTO) AS JSONHOLDER
SELECT [KEY] as ColumnName, [VALUE] as ColumnValue FROM (SELECT [KEY] AS OLDKEY, [VALUE] AS OLDVALUE  FROM @TEMP A
CROSS APPLY OPENJSON(A.JSONHOLDER)) B CROSS APPLY OPENJSON(B.OLDVALUE)