过滤Autodesk Vault垂直数据,获取每个图形的最新记录

时间:2016-12-16 15:11:20

标签: sql-server pivot autodesk

使用Microsoft SQL Server速成版(64位)10.0.550.0

我正在尝试从Autodesk Vault服务器中提取数据。获取所需数据所涉及的SQL对于我目前的知识水平而言过于先进,因此我尝试使用来自Google和StackOverflow的碎片作为碎片进行拼图。使用this excellent answer我能够将垂直数据转换为可管理的水平格式。

Autodesk Vault数据库存储有关CAD绘图的信息(以及其他内容)。主垂直表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的{​​{1}}数据类型。上面的查询产生类似于以下的数据集:

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) 的最新修订日期为“2016-12-16”等。

我还看了this answer关于如何分组和选择其中一列具有最大值的行,但我似乎无法弄清楚如何将两者结合起来。我尝试将以下代码段添加到上述查询中的注释行,但它在许多不同的级别上都失败了。

PartNumber=10001

我正在标记这个问题“枢轴”的原因,虽然旋转已经完成,但我怀疑旋转是导致我麻烦的原因。我还没有能够绕过这个旋转的东西,我的SQL优化技能严重缺乏。也许过滤应该在内心层面完成?

1 个答案:

答案 0 :(得分:0)

从@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)

集合中没有旧版本。