[英]How to use condition in XQuery?
I have sample xml data with address.我有带有地址的示例 xml 数据。 It works well but there's one problem.
它运作良好,但有一个问题。 I use "/" to concatenate house number and flat number but if there's no flat number I receive something like that: 1 /.
我使用“/”来连接门牌号码和单位号码,但如果没有单位号码,我会收到类似的信息:1 /。
Here's my example:这是我的例子:
declare @xml as xml = '<root>
<Row>
<proceeding>
<signatures>V GU 86/18</signatures>
<signatures>V GUp 9/19</signatures>
<signatures>V GUp 8/19</signatures>
</proceeding>
<entity>
<info>
<cleaned_name>Kate Smith</cleaned_name>
</info>
<address>
<town>London </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Downing Street</street>
<zip_code>00-001</zip_code>
</address>
<address>
<town>Yorkshire </town>
<house_number>1 </house_number>
<flat_number>1</flat_number>
<street>Morning Street</street>
<zip_code>00-999</zip_code>
</address>
</entity>
<entity>
<info>
<cleaned_name>John Smith</cleaned_name>
</info>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number>1</flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
<address>
<town>Washington </town>
<house_number>1</house_number>
<flat_number></flat_number>
<street>Pennsylvania Avenue</street>
<zip_code>00-001</zip_code>
</address>
</entity>
</Row>
</root>'
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
And that's my desired outcome:这就是我想要的结果:
Here's what I've tried so far:这是我迄今为止尝试过的:
declare @v varchar(20)='house_number'
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('if (sql:variable("@v")="") then for $s in entity/address
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1]
)}</x>
else
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>
')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
I receive the following error: XQuery [query()]: The variable '$s' was not found in the scope in which it was referenced.我收到以下错误:XQuery [query()]:在引用它的范围内找不到变量“$s”。 I'm wondering if I can achieve my goal in that way.
我想知道我是否可以通过这种方式实现我的目标。
I'm not quite sure what problem the other answers are solving, but for the question as described in the title, you can replace我不太确定其他答案正在解决什么问题,但是对于标题中描述的问题,您可以替换
($s/house_number/text())[1],"/",($s/flat_number/text())[1]
in the concat params with在 concat 参数中
string-join((($s/house_number/text())[1], ($s/flat_number/text())[1]), '/')
which will insert the "/" only if both house-number and flat-number exist.仅当门牌号和公寓号都存在时才会插入“/”。
I can't see why the [1]
subscripts are needed (perhaps to defeat static type-checking?) but I've left them in.我不明白为什么需要
[1]
下标(也许是为了打败静态类型检查?)但我已经把它们留在了。
I've done it other way and it works.我以其他方式完成了它并且它有效。
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
return
if ($s/flat_number="")
then
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1]
)}</x>
else
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,($s/house_number/text())[1],"/"
,($s/flat_number/text())[1]
)}</x>
')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
Well, in this case your last question's title (which I've changed in the meanwhile) "How to use LET" might have a revival :-)好吧,在这种情况下,您最后一个问题的标题(同时我已更改)“如何使用 LET”可能会复活:-)
Try this:尝试这个:
select
isnull(STUFF(a.x.query('for $s in entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu'
,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
,isnull(STUFF(a.x.query('for $s in entity/address
let $houseFlat:=if($s/flat_number/text())
then concat(($s/house_number/text())[1],"/",($s/flat_number/text())[1])
else string(($s/house_number/text())[1])
return
<x>{concat(", ",($s/zip_code/text())[1]," "
,($s/town/text())[1]," "
,($s/street/text())[1]," "
,$houseFlat
)}</x>')
.query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'')
from @xml.nodes('/root/Row') as a(x);
But - at least in this case - distinct-values()
will not help.但是 - 至少在这种情况下 -
distinct-values()
无济于事。 The both addresses are not identical due to 1
and 1/1
in the house and street number ...由于房屋和街道号码中的
1
和1/1
,这两个地址并不相同......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.