SQL Server,如何以“旋转”格式连接表(返回列而不是行)?

时间:2010-04-29 20:28:20

标签: sql sql-server-2005

对于蹩脚的头衔,我今天的描述技巧很差。

简而言之,我的查询类似于以下内容:

SELECT P.LAST_NAME, P.FIRST_NAME, D.DEMO_GROUP
FROM PERSON P
JOIN PERSON_DEMOGRAPHIC PD ON PD.PERSON_ID = P.PERSON_ID
JOIN DEMOGRAPHIC D ON D.DEMOGRAPHIC_ID = PD.DEMOGRAPHIC_ID

这会返回如下输出:

LAST_NAME      FIRST_NAME     DEMO_GROUP
---------------------------------------------
Johnson        Bob            Male
Smith          Jane           Female
Smith          Jane           Teacher
Beeblebrox     Zaphod         Male
Beeblebrox     Zaphod         Alien
Beeblebrox     Zaphid         Politician

我希望输出类似于以下内容:

LAST_NAME      FIRST_NAME     Male           Female         Teacher        Alien          Politician
---------------------------------------------------------------------------------------------------------
Johnson        Bob            1              0              0              0              0
Smith          Jane           0              1              1              0              0
Beeblebrox     Zaphod         1              0              0              1              1

DEMOGRAPHIC表中的行数各不相同,所以我不能肯定地说我需要多少列。查询需要灵活。

是的,在代码中执行此操作将是微不足道的。但是这个查询是一组复杂的存储过程,视图和报告服务的一部分,其中许多都在我的影响范围之外。我需要在数据库中生成此输出以避免破坏系统。有什么想法吗?

顺便说一下,这是MS SQL Server 2005。

感谢。

2 个答案:

答案 0 :(得分:3)

您可以使用PIVOT功能。这是一段代码。此函数需要提前输入列,但如果您不知道列数,则应进行动态SQL查询。看看this回答。

SELECT LAST_NAME, FIRST_NAME, [Male], [Female], [Alien], [Politician], [Teacher]
FROM 
(SELECT LAST_NAME, FIRST_NAME, DEMO_GROUP
FROM Person) p
PIVOT
(
COUNT (DEMO_GROUP)
FOR DEMO_GROUP IN
( [Male], [Female], [Alien], [Politician], [Teacher] )
) AS pvt
ORDER BY LAST_NAME

答案 1 :(得分:0)

假设要提交的Demo_Group列表是提前知道的,您可以执行以下操作:

SELECT P.LAST_NAME, P.FIRST_NAME
    , Sum( Case When Demo_Group = 'Male' Then 1 Else 0 End ) As Male
    , Sum( Case When Demo_Group = 'Female' Then 1 Else 0 End ) As Female
    , Sum( Case When Demo_Group = 'Teacher' Then 1 Else 0 End ) As Teacher
    , Sum( Case When Demo_Group = 'Alien' Then 1 Else 0 End ) As Alien
FROM PERSON P
    JOIN PERSON_DEMOGRAPHIC PD 
        ON PD.PERSON_ID = P.PERSON_ID
    JOIN DEMOGRAPHIC D 
        ON D.DEMOGRAPHIC_ID = PD.DEMOGRAPHIC_ID
Group By P.LAST_NAME, P.FIRST_NAME

如果Demo_Group值列表未知,这意味着您希望动态生成列,那么唯一的方法就是使用一些非常动态的SQL。这不是SQL的目的,而是应该在中间层或报告工具中完成。