Как преобразовать этот SQL-запрос в XQuery? - PullRequest
0 голосов
/ 05 ноября 2019

Как преобразовать этот запрос SQL в эквивалент XQuery

SELECT e.essn AS one, f.essn AS two, e.pno, f.pno 
FROM works_on AS e JOIN works_on AS f on e.pno = f.pno 
AND e.essn < f.essn \n" . "ORDER BY `e`.`pno` ASC

Я пробовал это до сих пор, но он не дает желаемых результатов

let $prods := doc("../company/works_on.xml")//works_on[pno = $project/pnumber]
for $d in distinct-values($prods/essn),
$n in distinct-values($prods[essn = $d]/pno)
return <result essn="{$d}" pno="{$n}"/>

Это примерXML-файла, который я использую.

<dataroot>

    <works_on>

        <essn>123456789</essn>

        <pno>1</pno>

        <hours>32.5</hours>

    </works_on>

    <works_on>

        <essn>123456789</essn>

        <pno>2</pno>

        <hours>7.5</hours>

    </works_on>

    <works_on>

        <essn>333445555</essn>

        <pno>2</pno>

        <hours>10</hours>

    </works_on>

    <works_on>

        <essn>333445555</essn>

        <pno>3</pno>

        <hours>10</hours>

    </works_on>

Это вывод на данный момент

<results>
  <project>
    <pnumber>1</pnumber>
    <employee>
      <essn>123456789</essn>
      <essn>453453453</essn>
    </employee>
  </project>
  <project>
    <pnumber>2</pnumber>
    <employee>
      <essn>123456789</essn>
      <essn>333445555</essn>
      <essn>453453453</essn>
    </employee>
  </project>
  <project>
    <pnumber>3</pnumber>
    <employee>
      <essn>333445555</essn>
      <essn>666884444</essn>
    </employee>
  </project>
  <project>
    <pnumber>10</pnumber>
    <employee>
      <essn>333445555</essn>
      <essn>987987987</essn>
      <essn>999887777</essn>
    </employee>
  </project>
  <project>
    <pnumber>20</pnumber>
    <employee>
      <essn>333445555</essn>
      <essn>888665555</essn>
      <essn>987654321</essn>
    </employee>
  </project>
  <project>
    <pnumber>30</pnumber>
    <employee>
      <essn>987654321</essn>
      <essn>987987987</essn>
      <essn>999887777</essn>
    </employee>
  </project>
</results>

Я пытаюсь получить значения для essn, например, в парах, на проекте1, это будет как есть, но для проекта 2 будет 123456789 и 333445555 в качестве одной пары, 123456789 и 453453453 в качестве другой пары и, наконец, 333445555 и 453453453 в качестве последней пары. Они должны быть неповторяющимися и не перевернутыми парами.

1 Ответ

0 голосов
/ 05 ноября 2019

Предоставленный вами XML сокращен для краткости (кстати, хорошая идея), но - что затрудняет понимание вашей проблемы - он больше не соответствует вашему ожидаемому результату.

На данный момент яЯ сижу перед SQL-сервером, поэтому тестовым кодом является T-SQL, но идея XQuery должна быть такой же, как и у других движков:

- Ваш XML

DECLARE @xml XML=
N'<dataroot>
  <works_on>
    <essn>123456789</essn>
    <pno>1</pno>
    <hours>32.5</hours>
  </works_on>
  <works_on>
    <essn>123456789</essn>
    <pno>2</pno>
    <hours>7.5</hours>
  </works_on>
  <works_on>
    <essn>333445555</essn>
    <pno>2</pno>
    <hours>10</hours>
  </works_on>
  <works_on>
    <essn>333445555</essn>
    <pno>3</pno>
    <hours>10</hours>
  </works_on>
</dataroot>'; 

- T-SQL-запрос со встроенным XQuery

SELECT @xml.query
('<results>
  {
  for $p in distinct-values(/dataroot/works_on/pno/text())
  order by $p
  return <project><pnumber>{$p}</pnumber>
         <employee>
         {
         for $e in distinct-values(/dataroot/works_on[pno=$p]/essn/text())
         order by $e
         return <essn>{$e}</essn>
         }
         </employee>
         </project>
  } 
  </results>')

Результат (для сокращенного XML)

<results>
  <project>
    <pnumber>1</pnumber>
    <employee>
      <essn>123456789</essn>
    </employee>
  </project>
  <project>
    <pnumber>2</pnumber>
    <employee>
      <essn>123456789</essn>
      <essn>333445555</essn>
    </employee>
  </project>
  <project>
    <pnumber>3</pnumber>
    <employee>
      <essn>333445555</essn>
    </employee>
  </project>
</results>

Идея вкратце:

Мы находим отдельный список номеров проектов и выписываем основную структуру вывода с номерами проектов. Внутри мы создаем элемент <employee> и заполняем его значениями <essn>, найденными ниже любого <works_on>, у которого имеет <pno> в качестве текущего числа .

Надеюсь, это поможет ...

...