1

我有一张随属性垂直增长的表格。我正在使用 PIVOT 将行值转换为列并获取所需的数据。现在,我正在尝试根据某个过滤器连接存储在两个单独行中的值。连接后,我只需要显示该组中的一行,第二行的 id 列应该作为结果集中的新列。

我有一个示例数据库表和一个我处理过的查询:

源表:

id  name
1   weight
2   height
3   bp-systolic
4   bp-diastolic
5   ABI
6   Notes
7   bp-systolic
8   bp-diastolic

属性表:

id  propertykey propertyvalue   
1   value       200
1   unit        lbs
1   ExtId       7
2   value       74
2   unit        in
2   ExtId       8
3   value       120
3   unit        mm[Hg]
3   ExtId       9
4   value       80
4   unit        mm[Hg]
4   ExtId       9
7   value       126
7   unit        mm[Hg]
7   ExtId       10
8   value       87
8   unit        mm[Hg]
8   ExtId       10

现在通过我的查询,我可以将这两个表加入到列中,如下所示:

id  name            desc        ExtId   related_id
1   weight          200 lbs     7   
2   height          74 in       8   
3   bp-systolic     120 mm[Hg]  9   
4   bp-diastolic    80 mm[Hg]   9   
7   bp-systolic     126 mm[Hg]  10  
8   bp-diastolic    87 mm[Hg]   10  

我使用了以下查询:

select  
    id,
    name,
    value + ' ' + unit [desc],
    '' as related_id
from (
        select s.ID, s.name, p.propertykey, p.propertyvalue from source S
        inner join properties P on s.ID = P.ID
        where s.name in ('height', 'weight', 'bp-systolic', 'bp-diastolic')

) as P
PIVOT (MAX([PropertyValue]) FOR [PropertyKey] IN ([Value], [Unit], [ExtId])) AS PT

如何合并/合并具有相同“ExtId”的“bp-systolic”和“bp-diastolic”的数据并显示如下一行:

id  name            desc        related_id
1   weight          200 lbs 
2   height          74 in   
3   bp-systolic     120/80          4
7   bp-systolic     126/87          8

请注意,related_id 从“bp-diastolic”中获取“id”列,因为它们是基于“ExtId”相关的。

这是我的测试数据库表:

create table source (id int, name varchar(30))
create table properties (id int, propertykey varchar(30), propertyvalue varchar(30))

insert into source values (1, 'weight')
insert into source values (2, 'height')
insert into source values (3, 'bp-systolic')
insert into source values (4, 'bp-diastolic')
insert into source values (5, 'ABI')
insert into source values (6, 'notes')

insert into properties values (1, 'value', '200')
insert into properties values (1, 'unit', 'lbs')
insert into properties values (1, 'ExtId', '7')
insert into properties values (2, 'value', '74')
insert into properties values (2, 'unit', 'in')
insert into properties values (2, 'ExtId', '8')
insert into properties values (3, 'value', '120')
insert into properties values (3, 'unit', 'mm[Hg]')
insert into properties values (3, 'ExtId', '9')    
insert into properties values (4, 'value', '80')
insert into properties values (4, 'unit', 'mm[Hg]')
insert into properties values (4, 'ExtId', '9')
insert into properties values (5, 'value', '123')
insert into properties values (6, 'value', 'this is a sample note')
4

2 回答 2

1

您可以将数据透视表中的结果插入到临时表中,然后进行自联接,以便获得所需的 id 和值。因此,假设该表已命名#measures,您可以执行以下操作:

create table #measures(id int, name varchar(50), value varchar(1000), extId varchar(3));

insert into #measures
(id, name)
select id, name from source;

update m
  set extid = ext.propertyvalue
from #measures m
join properties ext on m.id = ext.id
  and ext.propertykey = 'extid';

update m
  set value = nm.propertyvalue
from #measures m
join properties nm on m.id = nm.id
  and nm.propertykey = 'value';

update m
  set value = value + ' ' + nm.propertyvalue
from #measures m
join properties nm on m.id = nm.id
  and nm.propertykey = 'unit';


        SELECT prim.ExtId, 
                prim.id,
                CASE WHEN dias.id IS NOT NULL THEN 'blood pressure' ELSE prim.name END AS measure,
                CASE WHEN dias.id IS NOT NULL THEN prim.[value] + '/' + dias.[value] ELSE prim.[value] END AS [desc],
                dias.id AS related_id
            FROM #measures prim
            LEFT JOIN #measures dias
                ON prim.ExtId = dias.ExtId
                AND prim.name = 'bp-systolic'
                AND dias.[name] = 'bp-diastolic'
            WHERE prim.name <> 'bp-diastolic'

编辑:鉴于下面的评论,我已经对此进行了相当大的修改。示例也可以在这里找到:http ://sqlfiddle.com/#!3/ced9c/4

于 2013-03-18T20:06:56.353 回答
0

如果可以,请将设计更改为非EAV替代方案。带有列的表weight, height, bp-diastolic, bp-systolic会使查询变得更简单。重量存储在 LBS 中的事实不必存储在数据库中。由前端以最终用户选择的指标显示/编辑权重。

回到问题,在 EAV 中,您可以查找匹配的行,例如:

select  s.id
,       case when s.id = 3 then 'bloodpressure' else s.name end as name
,       max(case when p1.propertykey = 'value' then p1.propertyvalue end) +
        max(isnull('/' + p2.propertyvalue,'')) + 
        max(case when p1.propertykey = 'unit' then p1.propertyvalue end) as [desc]
,       max(p2.id) as related_id
from    source s
join    properties p1
on      s.id = p1.id
left join
        properties p2
on      p2.propertykey = 'value'
        and p2.id = 4 -- 4:bp-diastolic
        and p1.id = 3 -- 3:bp-systolic
where   s.id in (1,2,3) -- 1:weight, 2:height, 3:bp-systolic
group by
        s.id
,       s.name

SQL Fiddle 的示例。

于 2013-03-18T20:16:20.063 回答