2016-12-16 6 views
0

Использование Microsoft SQL Server Express Edition (64-разрядная версия) 10.0.550.0Фильтрация Autodesk Vault вертикальные данные, получать новейшую запись для каждого чертежа

Я пытаюсь извлечь данные с сервера Autodesk Vault. SQL, связанный с получением требуемых данных, слишком продвинут для моего текущего уровня знаний, поэтому я пытаюсь заложить головоломку, используя биты из Google и StackOverflow как части. Используя this excellent answer, я смог перенести вертикальные данные в управляемый горизонтальный формат.

В базе данных Autodesk Vault хранится информация о чертежах САПР (между прочим). В основной вертикальной таблице dbo.Property содержится информация обо всех различных версиях каждого чертежа САПР. Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я получаю слишком много данных. Мне просто нужны данные из последней редакции каждого чертежа САПР.

Вот мой 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 о том, как группировать и выбирать строки, где одно из столбцов имеет максимальное значение, но Я просто не могу понять, как их сочетать. Я попытался добавить следующий фрагмент в прокомментированную строку в указанном выше запросе, но он не работает на разных уровнях.

and (PartNumber, CreateDate) in 
(
    select PartNumber, max(CreateDate) 
    from t3 
    group by PartNumber 
) 

Причина, почему я разметил этот вопрос «шарнирный», хотя поворот уже сделан, то, что я подозреваю, что поворотное это то, что вызывает у меня неприятность. Я просто не смог обернуть голову вокруг этого поворотного материала, и мои навыки оптимизации SQL серьезно отсутствуют. Может быть, фильтрация должна выполняться на внутреннем уровне?

+0

'ВЫБЕРИТЕ x. FROM (ВАШ ВОПРОС ЗДЕСЬ) x JOIN (SELECT partnumber, MAX (CreateDate) FROM (ВАШ ВОПРОС ЗДЕСЬ) ГРУППА BY partnumber) y ON y.partnumber = x.partnumber И y.createdate = x.createdate' – Strawberry

+0

Я полагаю, что у вас есть хорошая причина не использовать [веб-службы] (https: //knowledge.autodesk.ком/поддержка/сводом продукты/узнать, исследовать/CAAS/CloudHelp/cloudhelp/2014/RUS/Vault/файлы/GUID-F21E7DD6-39E9-473C-84BB-3446BCAFCCC0-htm.html)? Из документов:> ** Прямой доступ ** и редактирование базы данных Vault строго запрещено. – Maxence

+0

@Maxence Не уверен, что это квалифицируется как хорошая причина или нет, но мне дали RDP серверу с открытым окном MSSQL SMS и попросил извлечь определенный набор данных из базы данных. Я не знал, что есть API. Я пробовал искать в Интернете документацию, но мне это не хватало. Есть ли REST API? Нам нужно получить доступ к Vault из простого веб-приложения. –

ответ

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) 

Нет более старые версии в наборе.