Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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_Tsql - Fatal编程技术网

如何在SQL中将行转换为列

如何在SQL中将行转换为列,sql,tsql,Sql,Tsql,有人能帮我处理这个SQL查询吗 在下表中,响应统计了段发生的次数 在检查日期回复 CREATE TABLE #TEST (ID INT, SEGMENT CHAR(1),RESPONSES INT,CHECKED SMALLDATETIME) INSERT INTO #TEST VALUES (1,'A',0,'2009-05-01') INSERT INTO #TEST VALUES (2,'B',1,'2009-05-01') INSERT INTO #TEST VALUES (3,'C',

有人能帮我处理这个SQL查询吗

在下表中,响应统计了段发生的次数 在检查日期回复

CREATE TABLE #TEST (ID INT, SEGMENT CHAR(1),RESPONSES
INT,CHECKED SMALLDATETIME)
INSERT INTO #TEST VALUES (1,'A',0,'2009-05-01')
INSERT INTO #TEST VALUES (2,'B',1,'2009-05-01')
INSERT INTO #TEST VALUES (3,'C',0,'2009-05-01')
INSERT INTO #TEST VALUES (4,'A',0,'2009-05-02')
INSERT INTO #TEST VALUES (5,'B',2,'2009-05-02')
INSERT INTO #TEST VALUES (6,'C',1,'2009-05-02')
INSERT INTO #TEST VALUES (7,'A',1,'2009-05-03')
INSERT INTO #TEST VALUES (8,'B',0,'2009-05-03')
INSERT INTO #TEST VALUES (9,'C',2,'2009-05-03')
编写一个查询,总结每个细分市场和每个细分市场的总响应 检查日期,以以下格式显示:

CHECKED      A      B       C
2009-5-01    0      1       0
2009-5-02    0      2       1
2009-5-03    1      0       2
不要将段名称(即“A”、“B”、“C”)硬编码到您的解决方案中,这样 如果添加了更多段(如“D”)或删除了段,则解决方案仍能正常工作
重命名(例如“A”->“X”)。

您需要使用动态SQL。看看这个例子。不同的博客,相同的方法


如果列是静态的,并且使用的是SQL Server 2005及更高版本,则可以使用该功能执行此类查询。

您需要使用动态SQL。看看这个例子。不同的博客,相同的方法

Select Checked
    , Sum( Case When Segment = 'A' Then 1 Else 0 End ) As A
    , Sum( Case When Segment = 'B' Then 1 Else 0 End ) As B
    , Sum( Case When Segment = 'C' Then 1 Else 0 End ) As C
From #Test
Group By Checked
如果列是静态的,并且使用的是SQL Server 2005及更高版本,则可以使用该功能执行此类查询

Select Checked
    , Sum( Case When Segment = 'A' Then 1 Else 0 End ) As A
    , Sum( Case When Segment = 'B' Then 1 Else 0 End ) As B
    , Sum( Case When Segment = 'C' Then 1 Else 0 End ) As C
From #Test
Group By Checked
这种类型的查询通常称为交叉表查询。上述解决方案假设您希望静态声明要查看的列。如果您想动态地确定列,那么您要寻找的是一个动态交叉表,而不能用SQL语言本机完成。SQL语言不是为动态列生成而设计的。解决方案是在中间层构建查询

这种类型的查询通常称为交叉表查询。上述解决方案假设您希望静态声明要查看的列。如果您想动态地确定列,那么您要寻找的是一个动态交叉表,而不能用SQL语言本机完成。SQL语言不是为动态列生成而设计的。解决方案是在中间层构建查询。

请参见:如果使用SQL Server 2005或更高版本

DECLARE  @test TABLE
(
    ID INT, 
    SEGMENT CHAR(1),
    RESPONSES INT,
    CHECKED SMALLDATETIME
)

INSERT INTO @test VALUES (1,'A',0,'2009-05-01')
INSERT INTO @test VALUES (2,'B',1,'2009-05-01')
INSERT INTO @test VALUES (3,'C',0,'2009-05-01')
INSERT INTO @test VALUES (4,'A',0,'2009-05-02')
INSERT INTO @test VALUES (5,'B',2,'2009-05-02')
INSERT INTO @test VALUES (6,'C',1,'2009-05-02')
INSERT INTO @test VALUES (7,'A',1,'2009-05-03')
INSERT INTO @test VALUES (8,'B',0,'2009-05-03')
INSERT INTO @test VALUES (9,'C',2,'2009-05-03')


SELECT * FROM 
(    
    SELECT  SEGMENT,
            RESPONSES,
            CHECKED
    FROM @test
) AS subquery 
PIVOT 
(
    SUM(responses) 
    FOR SEGMENT IN ([a],[b],[c])
) AS pivotquery

动态SQL示例

CREATE TABLE ##test
(
    ID INT, 
    SEGMENT CHAR(1),
    RESPONSES INT,
    CHECKED SMALLDATETIME
)

INSERT INTO ##test VALUES (1,'A',0,'2009-05-01')
INSERT INTO ##test VALUES (2,'B',1,'2009-05-01')
INSERT INTO ##test VALUES (3,'C',0,'2009-05-01')
INSERT INTO ##test VALUES (4,'A',0,'2009-05-02')
INSERT INTO ##test VALUES (5,'B',2,'2009-05-02')
INSERT INTO ##test VALUES (6,'C',1,'2009-05-02')
INSERT INTO ##test VALUES (7,'A',1,'2009-05-03')
INSERT INTO ##test VALUES (8,'B',0,'2009-05-03')
INSERT INTO ##test VALUES (9,'C',2,'2009-05-03')

DECLARE @SQLa VARCHAR(255),
        @SQLb VARCHAR(255),
        @SQLc VARCHAR(255)

SET @SQLa =
'SELECT * FROM 
(    
    SELECT  SEGMENT,
            RESPONSES,
            CHECKED
    FROM ##test
) AS subquery 
PIVOT 
(
    SUM(responses) 
    FOR SEGMENT IN ('

SET @SQLc = ')
) AS pivotquery'

SELECT @sqlB = STUFF(
(
    SELECT ',[' + SEGMENT + ']'
    FROM ##test WITH (NOLOCK)
    GROUP BY SEGMENT
    FOR XML PATH('')
),1, 1, '')

EXECUTE (@SQLa + @SQLb + @SQLc)

DROP TABLE ##test
请参阅:如果使用SQL Server 2005或更高版本

DECLARE  @test TABLE
(
    ID INT, 
    SEGMENT CHAR(1),
    RESPONSES INT,
    CHECKED SMALLDATETIME
)

INSERT INTO @test VALUES (1,'A',0,'2009-05-01')
INSERT INTO @test VALUES (2,'B',1,'2009-05-01')
INSERT INTO @test VALUES (3,'C',0,'2009-05-01')
INSERT INTO @test VALUES (4,'A',0,'2009-05-02')
INSERT INTO @test VALUES (5,'B',2,'2009-05-02')
INSERT INTO @test VALUES (6,'C',1,'2009-05-02')
INSERT INTO @test VALUES (7,'A',1,'2009-05-03')
INSERT INTO @test VALUES (8,'B',0,'2009-05-03')
INSERT INTO @test VALUES (9,'C',2,'2009-05-03')


SELECT * FROM 
(    
    SELECT  SEGMENT,
            RESPONSES,
            CHECKED
    FROM @test
) AS subquery 
PIVOT 
(
    SUM(responses) 
    FOR SEGMENT IN ([a],[b],[c])
) AS pivotquery

动态SQL示例

CREATE TABLE ##test
(
    ID INT, 
    SEGMENT CHAR(1),
    RESPONSES INT,
    CHECKED SMALLDATETIME
)

INSERT INTO ##test VALUES (1,'A',0,'2009-05-01')
INSERT INTO ##test VALUES (2,'B',1,'2009-05-01')
INSERT INTO ##test VALUES (3,'C',0,'2009-05-01')
INSERT INTO ##test VALUES (4,'A',0,'2009-05-02')
INSERT INTO ##test VALUES (5,'B',2,'2009-05-02')
INSERT INTO ##test VALUES (6,'C',1,'2009-05-02')
INSERT INTO ##test VALUES (7,'A',1,'2009-05-03')
INSERT INTO ##test VALUES (8,'B',0,'2009-05-03')
INSERT INTO ##test VALUES (9,'C',2,'2009-05-03')

DECLARE @SQLa VARCHAR(255),
        @SQLb VARCHAR(255),
        @SQLc VARCHAR(255)

SET @SQLa =
'SELECT * FROM 
(    
    SELECT  SEGMENT,
            RESPONSES,
            CHECKED
    FROM ##test
) AS subquery 
PIVOT 
(
    SUM(responses) 
    FOR SEGMENT IN ('

SET @SQLc = ')
) AS pivotquery'

SELECT @sqlB = STUFF(
(
    SELECT ',[' + SEGMENT + ']'
    FROM ##test WITH (NOLOCK)
    GROUP BY SEGMENT
    FOR XML PATH('')
),1, 1, '')

EXECUTE (@SQLa + @SQLb + @SQLc)

DROP TABLE ##test


这有点家庭作业的味道。是吗?@paul-这是一个采访问题,我无法回答:p简短的回答是,不能用SQL语言本机完成。它要么需要特定于供应商的扩展(例如Access的转换关键字),要么需要动态SQL,这应该在T-SQL之外完成。这有点像家庭作业。是吗?@paul-这是一个采访问题,我无法回答:p简短的回答是,不能用SQL语言本机完成。它需要特定于供应商的扩展(例如Access的转换关键字)或动态SQL,而动态SQL应该在T-SQL之外完成。动态SQL是唯一的其他方法。查看编辑到我的答案中的链接。动态查询是唯一的方法。使用PIVOT时,要透视的列必须在查询中列出,即PIVOT查询不能处理“动态段”,即最后一个条件“不要硬编码段名称…”不能用静态语句实现。@amit\u g:好的。为了强调这一点,我对答案进行了反复分析。动态SQL是唯一的另一种方法。查看编辑到我的答案中的链接。动态查询是唯一的方法。使用PIVOT时,要透视的列必须在查询中列出,即PIVOT查询不能处理“动态段”,即最后一个条件“不要硬编码段名称…”不能用静态语句实现。@amit\u g:好的。我把我的答案翻了个底朝天来强调这一事实。非常感谢,但我不想要一个固定的专栏。还有别的办法吗??如果是K、L和M,我不想将A、B和C重命名为K、L和M。@Kevin——正如我在回答的底部所修正的那样,这不能用SQL语言本机完成。唯一的解决方案是动态SQL,这不应该在T-SQL中完成。非常感谢,但我不想要修复列。还有别的办法吗??如果是K、L和M,我不想将A、B和C重命名为K、L和M。@Kevin——正如我在回答的底部所修正的那样,这不能用SQL语言本机完成。唯一的解决方案是动态SQL,它不应该在T-SQL中完成。您可以使用动态SQL(或函数)获取列名:a、B、C-如果您想要示例,请告诉我。@dan-请告诉我示例。凯文:对不起,昨晚的会议耽搁了。不过,直到现在我才意识到这是一个面试问题。这是否意味着我得到了这份工作?:)你资历太高了。这意味着您不明白:p您可以使用动态SQL(或函数)获取列名:a、B、C-如果您想要一个示例,请告诉我。@dan-请告诉我示例。凯文:对不起,昨晚的会议耽搁了。不过,直到现在我才意识到这是一个面试问题。这是否意味着我得到了这份工作?:)你资历太高了。这意味着你不明白:P