Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.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
Microsoft SQL Server:向行中添加新列而不是重复的值_Sql_Sql Server - Fatal编程技术网

Microsoft SQL Server:向行中添加新列而不是重复的值

Microsoft SQL Server:向行中添加新列而不是重复的值,sql,sql-server,Sql,Sql Server,以下是我目前的情况: 我看到了一个长长的数据列表,其中包含名称和值,以及相应的值ID。ID的数量可以根据显示的数据而变化,但对于整个集合来说是恒定的。此集合的每个名称正好有2个值。问题是,名称重复,但ID不重复。我的问题就变成了, 如何转换如下所示的表: Name | ID | Value Sam | 1 | 15 Sam | 2 | 6 Bob | 1 | 9 Bob | 2 | 11 Name | Value1 | Value2 Sam |

以下是我目前的情况:

我看到了一个长长的数据列表,其中包含名称和值,以及相应的值ID。ID的数量可以根据显示的数据而变化,但对于整个集合来说是恒定的。此集合的每个名称正好有2个值。问题是,名称重复,但ID不重复。我的问题就变成了,

如何转换如下所示的表:

Name | ID | Value
Sam  |  1 |    15
Sam  |  2 |     6
Bob  |  1 |     9
Bob  |  2 |    11
Name | Value1 | Value2
Sam  |     15 |      6
Bob  |      9 |     11
更像这样:

Name | ID | Value
Sam  |  1 |    15
Sam  |  2 |     6
Bob  |  1 |     9
Bob  |  2 |    11
Name | Value1 | Value2
Sam  |     15 |      6
Bob  |      9 |     11

注意:我发现很难找到这个问题的标题。

您可以使用pivot作为示例。请看以下代码片段:

SELECT pvt.Name, pvt.[1] as Value1, pvt.[2] as Value2
FROM yourTable
PIVTO (
    MAX(Value)
    FOR id IN([1],[2])
) as pvt
您只需将附加id添加到IN和SELECT中

如果您需要动态轴,可以在此处使用此轴:

DECLARE @sql nvarchar(max), @columnlist nvarchar(max)

SELECT @columnlist = 
        COALESCE(@columnlist + N',['+CONVERT(nvarchar(max),cols.id)+']', 
            N'['+CONVERT(nvarchar(max),cols.id)+']'
        )
FROM (SELECT DISTINCT id FROM yourTable) as cols

-- this is your part
SET @sql = N'
    SELECT pvt.*
    FROM yourTable
    PIVTO (
        MAX(Value)
        FOR id IN('+@columnlist+')
    ) as pvt'
EXEC(@sql)

如果可以确保集合只有两个值,并且这些值的ID始终为1或2,则可以执行以下操作:

CREATE TABLE #Table (Name VARCHAR(5), ID INT, Value INT)
INSERT INTO #Table VALUES ('Sam', 1, 15), ('Sam', 2, 6), ('Bob', 1, 9), ('Bob', 2, 11)

SELECT  t.Name,
        t.Value AS Value1,
        t2.Value AS Value2
  FROM  #Table t
    INNER JOIN #Table t2 ON t2.Name = t.Name AND t2.ID = 2
  WHERE t.ID = 1

DROP TABLE #Table
请注意,临时表仅用于说明结果。重要的是SELECT语句


这会将表连接到自身以获取Value2的值。

您需要的是一个PIVOT查询。根据您的数据集中有多少个名称,以及您是否提前知道它们,您可能需要一个动态轴心

Pivot查询可能有点混乱。但这里有两个示例说明如何构建动态透视查询。第二个问题是另一个堆栈溢出问题,可能比第一个问题更适合您的情况

编辑:具体示例

-- DROP TABLE #MyTable
-- CREATE TABLE #MyTable( name varchar(10), ID int, value int );

INSERT #MyTable VALUES ('Sam', 1, 15);
INSERT #MyTable VALUES ('Sam', 2, 6);
INSERT #MyTable VALUES ('Bob', 1, 9);
INSERT #MyTable VALUES ('Bob', 2, 11);
-- INSERT #MyTable VALUES ('Sam', 3, 1);
-- INSERT #MyTable VALUES ('Bob', 3, 2);


DECLARE @cols NVARCHAR(2000) 
DECLARE @query NVARCHAR(4000) 

SELECT  @cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT 
                                '],[' + CONVERT(varchar(5), t.ID )
                        FROM    #MyTable AS t 
                        --ORDER BY '],[' + t.ID 
                        FOR XML PATH('') 
                      ), 1, 2, '') + ']' 

--SELECT  @cols

SET @query = N'SELECT name,'+ @cols +' FROM 
(SELECT t1.name, t1.ID, t1.Value FROM #MyTable AS t1) p 
PIVOT (MAX([Value]) FOR ID IN ( '+ @cols +' )) 
AS pvt;' 

EXECUTE(@query)

您需要重写此查询以添加/删除连接操作,具体取决于与每个名称关联的值的数量。我认为pivot是解决整个问题的一个更稳健的解决方案,尽管这个解决方案在提供的具体示例中足够有效。我同意pivot是一个更合适的解决方案,但是当OP指示只有两个值时,这将执行得更快。实际上,OP指示,ID的数量可能因提供的数据而异,但本例中每个名称正好有2个值。@死区在这种情况下,PIVOT也不能解决问题,因为它会将每个单独的ID透视到它自己的列中。我很困惑。。。这不正是OP想要的吗?每个ID都成为它自己的列,列中列出了值。这也正是你的查询所做的,只是它被硬编码为值1和2。这似乎正是我想要的。我尝试使用这段代码,每个名称有3个和4个值,效果非常好。谢谢@DeadZone