过滤 Autodesk Vault 垂直数据,获取每个图形的最新记录
Filtering Autodesk Vault vertical data, getting the newest record for each drawing
使用 Microsoft SQL 服务器快捷版(64 位)10.0.550.0
我正在尝试从 Autodesk Vault 服务器中提取数据。获取所需数据所涉及的 SQL 对于我目前的知识水平来说太高级了,因此我尝试使用 Google 和 Whosebug 中的位来拼图。使用 this excellent answer 我能够将垂直数据转换为易于管理的水平格式。
Autodesk Vault 数据库存储有关 CAD 工程图(以及其他信息)的信息。主垂直 table dbo.Property
包含有关每个 CAD 绘图的所有不同修订的信息。我目前面临的问题是我得到的数据太多了。我只想要每个 CAD 图纸的最新修订版中的数据。
这是我目前的SQL
select
CreateDate,
EntityID,
PartNumber,
CategoryName,
[Subject],
Title
from
(
select
EntityID,
CreateDate,
[53] as PartNumber,
[28] as CategoryName,
[42] as [Subject],
[43] as Title
from
(
select
p.Value,
p.PropertyDefID,
p.EntityID,
e.CreateDate
from dbo.Property as p
inner join dbo.Entity as e on p.EntityID = e.EntityId
where p.PropertyDefID in(28, 42, 43, 53)
and e.EntityClassID = 8
) t1
pivot
(
max(Value)
for PropertyDefID in([28], [42], [43], [53])
) t2
) t3
where PartNumber is not null
and PartNumber != ''
and CategoryName = 'Drawing'
-- (1) additional condition
order by PartNumber, CreateDate desc
其中 dbo.Property.Value
是 sql_variant
数据类型。上面的查询结果类似于这样的数据集:
CreateDate | EntityID | PartNumber | CategoryName | Subject | Title
---------------------------------------------------------------------
2016-01-01 | 59046 | 10001 | Drawing | Xxxxx | Yyyyy
2016-05-01 | 60137 | 10001 | Drawing | Xxxxx | Yyyyy
2016-08-01 | 62518 | 10001 | Drawing | Xxxx | Yyyyyy
2016-12-16 | 63007 | 10001 | Drawing | Xxxxxx | Yyyyyy
2016-01-01 | 45776 | 10002 | Drawing | Zzzzz | NULL
2016-11-01 | 65011 | 10002 | Drawing | Zzzzzz | NULL
...
(about 23000 rows)
我遇到的问题是我正在获取每张图纸的所有修订。在上面的示例中,我只想要 PartNumber=10001
日期为“2016-12-16”等的最新版本
我还查看了 this answer 如何分组和 select 行其中一列具有最大值,但我似乎无法弄清楚如何组合二。我尝试将以下代码片段添加到上述查询的注释行中,但它在许多不同的级别上都失败了。
and (PartNumber, CreateDate) in
(
select PartNumber, max(CreateDate)
from t3
group by PartNumber
)
我标记这个问题的原因 "pivot",虽然旋转已经完成,但我怀疑旋转是给我带来麻烦的原因。我只是还不能完全理解这个旋转的东西,而且我的 SQL 优化技能严重缺乏。也许应该在内部级别进行过滤?
从@Strawberry 提供的评论中汲取灵感,我不断地工作和调整,直到我得到似乎可行的东西。我必须在 PIVOT
中使用 PIVOT
才能正常工作。
编辑: 起初我使用视图,但后来因为我必须使用只读数据库用户而改变了先决条件。幸运的是,我仍然被允许创建临时表。
这是最终结果。
if object_id('tempdb.dbo.#Properties', 'U') is not null
drop table #Properties
create table #Properties
(
PartNumber nvarchar(max),
[Subject] nvarchar(max),
Title nvarchar(max),
CreateDate datetime
)
insert into #Properties
(
PartNumber,
[Subject],
Title,
CreateDate
)
select
convert(nvarchar(max), PartNumber),
convert(nvarchar(max), [Subject]),
convert(nvarchar(max), Title),
convert(datetime, CreateDate)
from
(
select
EntityID,
CreateDate,
[53] as PartNumber,
[42] as [Subject],
[43] as Title
from
(
select
p.Value,
p.PropertyDefID,
p.EntityID,
e.CreateDate
from dbo.Property as p
inner join dbo.Entity as e on p.EntityID = e.EntityId
where p.PropertyDefID in (42, 43, 53)
and e.EntityClassID = 8
and p.EntityID in
(
select
max(EntityID) as MaxEntityID
from
(
select
EntityID,
[28] as CategoryName,
[53] as PartNumber
from
(
select
p.Value,
p.EntityID,
p.PropertyDefID
from dbo.Property as p
inner join dbo.Entity as e on p.EntityID = e.EntityId
where p.PropertyDefID in (28, 53)
and e.EntityClassID = 8 -- FileIteration
) as t1
pivot
(
max(Value)
for PropertyDefID in ([28], [53])
) as t2
) as t3
where CategoryName = 'Drawing'
group by PartNumber
)
) as t4
pivot
(
max(Value)
for PropertyDefID in ([42], [43], [53])
) as t5
) as t6
where PartNumber is not null
and PartNumber != ''
order by PartNumber
select * from #Properties;
-- search conditions goes here
我不得不将建议的 join
更改为 where x in(y)
,因为连接非常慢(四分钟后我终止了查询)。现在生成的数据集(生成需要约 2 秒)看起来很有希望:
PartNumber | Subject | Title | CreateDate | ...
-----------------------------------------------------------------------
100000 | Xxxxxx | Yyyyyy | 2015-08-17 09-10 | ...
100001 | Zzzzzz | NULL | 2015-09-02 15-23 | ...
...
(about 8900 rows)
集合中没有更多的旧修订。
使用 Microsoft SQL 服务器快捷版(64 位)10.0.550.0
我正在尝试从 Autodesk Vault 服务器中提取数据。获取所需数据所涉及的 SQL 对于我目前的知识水平来说太高级了,因此我尝试使用 Google 和 Whosebug 中的位来拼图。使用 this excellent answer 我能够将垂直数据转换为易于管理的水平格式。
Autodesk Vault 数据库存储有关 CAD 工程图(以及其他信息)的信息。主垂直 table dbo.Property
包含有关每个 CAD 绘图的所有不同修订的信息。我目前面临的问题是我得到的数据太多了。我只想要每个 CAD 图纸的最新修订版中的数据。
这是我目前的SQL
select
CreateDate,
EntityID,
PartNumber,
CategoryName,
[Subject],
Title
from
(
select
EntityID,
CreateDate,
[53] as PartNumber,
[28] as CategoryName,
[42] as [Subject],
[43] as Title
from
(
select
p.Value,
p.PropertyDefID,
p.EntityID,
e.CreateDate
from dbo.Property as p
inner join dbo.Entity as e on p.EntityID = e.EntityId
where p.PropertyDefID in(28, 42, 43, 53)
and e.EntityClassID = 8
) t1
pivot
(
max(Value)
for PropertyDefID in([28], [42], [43], [53])
) t2
) t3
where PartNumber is not null
and PartNumber != ''
and CategoryName = 'Drawing'
-- (1) additional condition
order by PartNumber, CreateDate desc
其中 dbo.Property.Value
是 sql_variant
数据类型。上面的查询结果类似于这样的数据集:
CreateDate | EntityID | PartNumber | CategoryName | Subject | Title
---------------------------------------------------------------------
2016-01-01 | 59046 | 10001 | Drawing | Xxxxx | Yyyyy
2016-05-01 | 60137 | 10001 | Drawing | Xxxxx | Yyyyy
2016-08-01 | 62518 | 10001 | Drawing | Xxxx | Yyyyyy
2016-12-16 | 63007 | 10001 | Drawing | Xxxxxx | Yyyyyy
2016-01-01 | 45776 | 10002 | Drawing | Zzzzz | NULL
2016-11-01 | 65011 | 10002 | Drawing | Zzzzzz | NULL
...
(about 23000 rows)
我遇到的问题是我正在获取每张图纸的所有修订。在上面的示例中,我只想要 PartNumber=10001
日期为“2016-12-16”等的最新版本
我还查看了 this answer 如何分组和 select 行其中一列具有最大值,但我似乎无法弄清楚如何组合二。我尝试将以下代码片段添加到上述查询的注释行中,但它在许多不同的级别上都失败了。
and (PartNumber, CreateDate) in
(
select PartNumber, max(CreateDate)
from t3
group by PartNumber
)
我标记这个问题的原因 "pivot",虽然旋转已经完成,但我怀疑旋转是给我带来麻烦的原因。我只是还不能完全理解这个旋转的东西,而且我的 SQL 优化技能严重缺乏。也许应该在内部级别进行过滤?
从@Strawberry 提供的评论中汲取灵感,我不断地工作和调整,直到我得到似乎可行的东西。我必须在 PIVOT
中使用 PIVOT
才能正常工作。
编辑: 起初我使用视图,但后来因为我必须使用只读数据库用户而改变了先决条件。幸运的是,我仍然被允许创建临时表。
这是最终结果。
if object_id('tempdb.dbo.#Properties', 'U') is not null
drop table #Properties
create table #Properties
(
PartNumber nvarchar(max),
[Subject] nvarchar(max),
Title nvarchar(max),
CreateDate datetime
)
insert into #Properties
(
PartNumber,
[Subject],
Title,
CreateDate
)
select
convert(nvarchar(max), PartNumber),
convert(nvarchar(max), [Subject]),
convert(nvarchar(max), Title),
convert(datetime, CreateDate)
from
(
select
EntityID,
CreateDate,
[53] as PartNumber,
[42] as [Subject],
[43] as Title
from
(
select
p.Value,
p.PropertyDefID,
p.EntityID,
e.CreateDate
from dbo.Property as p
inner join dbo.Entity as e on p.EntityID = e.EntityId
where p.PropertyDefID in (42, 43, 53)
and e.EntityClassID = 8
and p.EntityID in
(
select
max(EntityID) as MaxEntityID
from
(
select
EntityID,
[28] as CategoryName,
[53] as PartNumber
from
(
select
p.Value,
p.EntityID,
p.PropertyDefID
from dbo.Property as p
inner join dbo.Entity as e on p.EntityID = e.EntityId
where p.PropertyDefID in (28, 53)
and e.EntityClassID = 8 -- FileIteration
) as t1
pivot
(
max(Value)
for PropertyDefID in ([28], [53])
) as t2
) as t3
where CategoryName = 'Drawing'
group by PartNumber
)
) as t4
pivot
(
max(Value)
for PropertyDefID in ([42], [43], [53])
) as t5
) as t6
where PartNumber is not null
and PartNumber != ''
order by PartNumber
select * from #Properties;
-- search conditions goes here
我不得不将建议的 join
更改为 where x in(y)
,因为连接非常慢(四分钟后我终止了查询)。现在生成的数据集(生成需要约 2 秒)看起来很有希望:
PartNumber | Subject | Title | CreateDate | ...
-----------------------------------------------------------------------
100000 | Xxxxxx | Yyyyyy | 2015-08-17 09-10 | ...
100001 | Zzzzzz | NULL | 2015-09-02 15-23 | ...
...
(about 8900 rows)
集合中没有更多的旧修订。