1

我正在尝试获取我拥有的三个表,并以用户要求我这样做的方式显示数据。桌子看起来像这样。(我应该补充一点,我正在使用 MS SQL Server)

第一个表:ID 是 varchar,因为这是他们用来识别资产的 ID,并且他们使用数字和字母。

    aID| status | group   |
    -----------------------
    1  |   acti |  group1 |
    2  |   inac |  group2 |
   A3  |   acti |  group1 |

第二张桌子:这张桌子是固定的。它有大约 20 个值,ID 都是数字

    atID| traitname  |
    ------------------
     1  |   trait1   |
     2  |   trait2   |
     3  |   trait3   |

第三张表:该表用于识别第一张表中的资产所具有的特征。与上述表格中的字段同名的字段显然是有关联的。

tID|   aID  |   atID |   trait   |
----------------------------------
1  |   1    |    1   |   NAME    |
2  |   1    |    2   |   INFO    |
3  |   2    |    3   |   GOES    |
4  |   2    |    1   |   HERE    |
5  |   A3   |    2   |   HAHA    |

现在,用户希望程序以以下格式输出数据:

aID| status | group  | trait1 | trait2 | trait 3
-------------------------------------------------
1  |  acti  |  group1 |  NAME |  INFO  | NULL
2  |  inac  |  group2 |  HERE |  NULL  | GOES
A3 |  acti  |  group1 |  NULL |  HAHA  | NULL

我知道要实现这一点,我必须在 SQL 中使用 Pivot 命令。但是,我已经阅读并试图理解它,但我似乎无法理解它。尤其是它要求 MAX 值的部分。我不明白为什么我需要那个 MAX。

另外,我看到的示例是针对一张桌子的。我不确定我是否可以用三张桌子做到这一点。我确实有一个查询,将他们三个与我需要的信息连接起来。但是,我不知道如何从那里开始。请,对此的任何帮助将不胜感激。谢谢你。

4

1 回答 1

4

有几种方法可以获得结果,包括使用 PIVOT 函数。

您可以将聚合函数与 CASE 表达式一起使用:

select t1.aid, t1.status, t1.[group],
  max(case when t2.traitname = 'trait1' then t3.trait end) trait1,
  max(case when t2.traitname = 'trait2' then t3.trait end) trait2,
  max(case when t2.traitname = 'trait3' then t3.trait end) trait3
from table1 t1
inner join table3 t3
  on t1.aid = t3.aid
inner join table2 t2
  on t3.atid = t2.atid
group by t1.aid, t1.status, t1.[group];

请参阅带有演示的 SQL Fiddle

PIVOT 函数需要一个聚合函数,这就是您需要使用 MIN 或 MAX 函数的原因(因为您有一个字符串值)。

如果您的数量有限,traitnames则可以对查询进行硬编码:

select aid, status, [group],
  trait1, trait2, trait3
from
(
  select t1.aid,
    t1.status,
    t1.[group],
    t2.traitname,
    t3.trait
  from table1 t1
  inner join table3 t3
    on t1.aid = t3.aid
  inner join table2 t2
    on t3.atid = t2.atid
) d
pivot
(
  max(trait)
  for traitname in (trait1, trait2, trait3)
) piv;

请参阅SQL Fiddle with Demo

如果您有未知数量的值,那么您将希望使用动态 SQL 来获得最终结果:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(traitname) 
                    from Table2
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT aid, status, [group],' + @cols + ' 
            from 
            (
              select t1.aid,
                t1.status,
                t1.[group],
                t2.traitname,
                t3.trait
              from table1 t1
              inner join table3 t3
                on t1.aid = t3.aid
              inner join table2 t2
                on t3.atid = t2.atid
            ) x
            pivot 
            (
                max(trait)
                for traitname in (' + @cols + ')
            ) p '

execute sp_executesql @query;

请参阅带有演示的 SQL Fiddle

于 2013-09-24T15:02:58.057 回答