2016-11-09 4 views
2

Извините: этот пост получил немного долго (хотел убедиться, что все соответствующие было в)Запросы (много) XML данных для конкретного текста с в XML-элементы (TSQL)

Борясь, чтобы обернуть мой мозг вокруг это немного. У меня есть таблица, которая имеет 5 столбцов

ID (varchar) 
Record value(XML) 
date (datetime) 
applicationtypeid (int) 
applicationstatusid(int) 

XML содержит много данных, но часть меня интересует, как это выглядит.

<GoodsAndServicesItemSummaryViewModelItems> 
    <GoodsAndServicesMasterViewModel> 
    <Id>1</Id> 
    <ClassId>1</ClassId> 
    <TermsText>text</TermsText> 
    <TermsCreationType>ManuallyEntered</TermsCreationType> 
    <Terms /> 

В частности, элемент «TermsCreationType». В нем может быть один из следующих 3-х строк:

  • ManuallyEntered
  • CopyFromExistingMarks
  • CopyFromPreapprovedTermsDatabase

В зависимости от того, что файлы клиент там также может представлять собой смесь всех трех, и они могли бы содержат столько из этих смесей, сколько они теоретически желательны, например:

</PriorityClaimAdditionalDetailWizardStepViewModel> 
    <GoodsAndServicesMasterViewModel> 
    <Id>9</Id> 
    <ClassId>2</ClassId> 
    <TermsText>texty</TermsText> 
    <TermsCreationType>ManuallyEntered</TermsCreationType> 
    <Terms /> 
    </GoodsAndServicesMasterViewModel> 
    <GoodsAndServicesMasterViewModel> 
    <Id>10</Id> 
    <ClassId>1</ClassId> 
    <TermsText>text</TermsText> 
    <TermsCreationType>ManuallyEntered</TermsCreationType> 
    <Terms /> 
    </GoodsAndServicesMasterViewModel> 
</GoodsAndServicesItemSummaryViewModelItems> 
<GoodsAndServicesItemSummaryViewModelItemsUnMerged> 
    <GoodsAndServicesMasterViewModel> 
    <Id>9</Id> 
    <ClassId>9</ClassId> 
    <TermsText>test</TermsText> 
    <TermsCreationType>CopyFromExistingMarks</TermsCreationType> 
    <Terms /> 
    </GoodsAndServicesMasterViewModel> 

Я пытаюсь найти подсчет, сколько записей из определенного диапазона дат,

  1. содержит только один из указанных выше (появляется ли он один раз или даже в 50 раз до тех пор, как это единственное значение в том, что элемент)

  2. Записи, содержащие любую смесь из трех.


Моя попытка до сих пор, для «одного элемента только» таким образом:

SELECT Count (id) [pre-approved only] 
FROM [TMWebForms].[dbo].[webformapplication] 
WHERE trademarkid NOT IN (SELECT id 
          FROM [TMWebForms].[dbo].[webformapplication] 
          WHERE applicationtypeid = '5' 
            AND createddate BETWEEN '2016-08-01' AND '2016-08-31' 
            AND RECORDDATA.value('contains((//GoodsAndServicesWizardStepViewModel/GoodsAndServicesItemSummaryViewModelItems/GoodsAndServicesMasterViewModel/TermsCreationType/text())[1], "ManuallyEntered")', 'bit') = 1 
            AND applicationstatusid = 50 
            AND applicationtypeid = 5) 
     AND id NOT IN (SELECT id 
         FROM [TMWebForms].[dbo].[webformapplication] 
         WHERE applicationtypeid = '5' 
          AND createddate BETWEEN '2016-08-01' AND '2016-08-31' 
          AND RECORDDATA.value('contains((//GoodsAndServicesWizardStepViewModel/GoodsAndServicesItemSummaryViewModelItems/GoodsAndServicesMasterViewModel/TermsCreationType/text())[1], "CopyFromExistingMark")', 'bit') = 1 
          AND applicationstatusid = 50 
          AND applicationtypeid = 5) 
     AND createddate BETWEEN '2016-08-01' AND '2016-08-31' 
     AND RECORDDATA.value('contains((//GoodsAndServicesWizardStepViewModel/GoodsAndServicesItemSummaryViewModelItems/GoodsAndServicesMasterViewModel/TermsCreationType/text())[1], "CopyFromPreapprovedTermsDatabase")', 'bit') = 1 
     AND applicationstatusid = 50 
     AND applicationtypeid = 5 
  1. Это долго наматывается и не лучшее исполнение мудры длинный выстрел! (я подумал о том, чтобы преобразовать его в строку, а затем использовать «как» - но это, вероятно, так же плохо, если не хуже)

  2. Это не тянет именно то, что я хотел вернуть. Для меня он ищет только «CopyFromPreapprovedTermsDatabase», но при опросе данных есть несколько случаев, когда это первая строка, но я также вижу, что существует «вручную».

Любая помощь оценивается здесь!

+0

@Shnugo Привет, к сожалению, что я опубликовал первоначально, был приведенный пример. Теперь я отредактировал оригинальный пост и скопировал пример непосредственно из записи базы данных (включая конечный элемент предыдущего раздела, чтобы вы могли видеть, как он начинается), чтобы он был действительным. Что касается закрывающего элемента , это именно то, как оно написано в БД. Out put - я просто хочу подсчет. ничто иное, как фигура, рассказывающая мне, сколько из каждого я указал в первом «1. и 2.», моего сообщения. Спасибо. – Nighthawkz

+0

Извините, я не смотрел достаточно внимательно ... Опубликованный XML ** теперь ** недействителен, но я могу легко отремонтировать его, чтобы настроить * макет * ... – Shnugo

ответ

1

Попробуйте, как это

(я должен был добавить root и добавить открывающий и закрывающий теги)

DECLARE @xml XML= 
N'<SomeRoot> 
    <GoodsAndServicesItemSummaryViewModelItems> 
    <GoodsAndServicesMasterViewModel> 
     <Id>9</Id> 
     <ClassId>2</ClassId> 
     <TermsText>texty</TermsText> 
     <TermsCreationType>ManuallyEntered</TermsCreationType> 
     <Terms /> 
    </GoodsAndServicesMasterViewModel> 
    <GoodsAndServicesMasterViewModel> 
     <Id>10</Id> 
     <ClassId>1</ClassId> 
     <TermsText>text</TermsText> 
     <TermsCreationType>ManuallyEntered</TermsCreationType> 
     <Terms /> 
    </GoodsAndServicesMasterViewModel> 
    </GoodsAndServicesItemSummaryViewModelItems> 
    <GoodsAndServicesItemSummaryViewModelItemsUnMerged> 
    <GoodsAndServicesMasterViewModel> 
     <Id>9</Id> 
     <ClassId>9</ClassId> 
     <TermsText>test</TermsText> 
     <TermsCreationType>CopyFromExistingMarks</TermsCreationType> 
     <Terms /> 
    </GoodsAndServicesMasterViewModel> 
    </GoodsAndServicesItemSummaryViewModelItemsUnMerged> 
</SomeRoot>'; 

DECLARE @tbl TABLE(ID VARCHAR(10),Record_Value XML,[date] DATETIME,applicationtypeid INT,applicationstautsid INT); 
INSERT INTO @tbl VALUES('SomeTest',@xml,GETDATE(),11,22); 

--The КТР будет выбрать все столбцы и добавить фактический подсчет TermsCreationType с данным text()

WITH CTE AS 
(
    SELECT * 
      ,Record_Value.value('count(//TermsCreationType[text()="ManuallyEntered"])','int') AS CountManuallyEntered 
      ,Record_Value.value('count(//TermsCreationType[text()="CopyFromExistingMarks"])','int') AS CountCopyFromExistingMarks 
      ,Record_Value.value('count(//TermsCreationType[text()="CopyFromPreapprovedTermsDatabase"])','int') AS CountCopyFromPreapprovedTermsDatabase 
    FROM @tbl 
) 

--The окончательный SELECT использует в качестве большой CASE WHEN иерархии для анализа counts

SELECT * 
     ,CASE WHEN CTE.CountManuallyEntered=0 AND CTE.CountCopyFromExistingMarks=0 AND CTE.CountCopyFromPreapprovedTermsDatabase=0 THEN 'None' 
     ELSE 
      CASE WHEN CTE.CountManuallyEntered>0 AND CTE.CountCopyFromExistingMarks=0 AND CTE.CountCopyFromPreapprovedTermsDatabase=0 THEN 'Manually' 
      ELSE 
       CASE WHEN CTE.CountManuallyEntered=0 AND CTE.CountCopyFromExistingMarks>0 AND CTE.CountCopyFromPreapprovedTermsDatabase=0 THEN 'Existing' 
       ELSE 
        CASE WHEN CTE.CountManuallyEntered=0 AND CTE.CountCopyFromExistingMarks=0 AND CTE.CountCopyFromPreapprovedTermsDatabase>0 THEN 'Preapproved' 
        ELSE 
        'Mixed' 
        END 
       END 
      END 
     END AS CountAnalysis 
FROM CTE; 
+0

Спасибо! это именно то, что мне нужно. Я смог заставить его напрямую запросить мой стол. И он дает мне именно то число, которое мне нужно. Он также сообщил мне о другом синтаксисе xpath. Я пытался сделать все, используя «содержит». Даже не понял, что счет был вариантом! Это будет очень удобно в будущем. еще раз спасибо – Nighthawkz

 Смежные вопросы

  • Нет связанных вопросов^_^