将 STUFF 与 DATE 一起使用
Posted
技术标签:
【中文标题】将 STUFF 与 DATE 一起使用【英文标题】:Using STUFF with DATE 【发布时间】:2019-01-29 11:42:09 【问题描述】:我正在尝试使用 SQL Server 2016 中的 STUFF 功能来选择 DATE 信息并将其返回到表中。有时会有多个日期返回。我已经使用 STUFF 来获取我需要的其他数据。
Email = STUFF((SELECT ', ' + [Value]
FROM EmailTable
WHERE ID = r.ID AND EmailType = 1
FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,2,'')
这可以在适用的情况下返回多封电子邮件并且工作正常。现在的问题是我想做同样的事情,但要使用 DATE。
Date = STUFF((SELECT ', ' + DateValue
FROM DateTable
WHERE ID = r.ID
FOR XML PATH(''),TYPE).value('(./text())[1]','DATE'),1,2,'')
上面的代码sn-ps只是例子,表名和变量名在现实中是不同的,但它们应该能传达我的意思。
最后一个代码sn-p的错误是因为'+'符号它不起作用。如果我把逗号加出来,我可以让它返回 DATE,但它们被包裹在 XML 标记中。
它还必须返回一个 DATE 值,它不能转换为 NVARCHAR。
我不确定我所追求的是否可行,但我想我会问。
如果需要更多信息,请询问。
【问题讨论】:
您正在尝试连接字符串,而不是将STUFF
与DATE
一起使用。 SQL Server 2017 引入了 STRING_AGG,因此无需使用此类字符串连接技术。
你能分享示例输入和所需的输出
@Panagiotis 目前我无法使用 SQL Server 2017。
由于您想连接字符串,并且不想让日期格式留给机会,请使用FORMAT()
将日期格式化为您想要的字符串
“它还必须返回一个 DATE 值”——“它”指的是什么?您将一堆日期连接成一个字符串。不管怎样,这不会是一个单一的DATE
值。添加更多输入和所需输出可能会有所帮助。
【参考方案1】:
评论太长了。
您的代码不能在单个列中返回多个日期值。 SQL Server 不提供数组类型 - 或它们的等价物。
FOR XML PATH
所做的是产生一个字符串。该字符串被格式化为 XML,但它仍然是一个字符串。在字符串中,您可以识别属性的类型。但是,表示形式是字符串。
您可以做的最好的是将日期存储为 YYYY-MM-DD 或 YYYYMMDD,这很容易在 SQL Server(以及几乎任何其他软件)中转换为日期。
【讨论】:
我明白了。感谢您简单地为我介绍,现在一切都说得通了。我太专注于问题的 DATE 部分,而忽略了我正在尝试使用 XML 的事实。【参考方案2】:您在旧 SQL Server 版本中使用的字符串聚合技术中发布的内容。 SQL Server 2017 为此提供了 STRING_AGG。
此技术使用空字符串作为元素名称从查询中生成 XML 值。 .value('(./text())[1]','NVARCHAR(MAX)')
最后将 XML 值转换为 text 。最后,STUFF, 1,2,'')
删除了前导分隔符。
由于您想要连接字符串,并且不想让日期格式留给机会,请使用 FORMAT() 将日期格式化为您想要的字符串:
Email = STUFF((SELECT ', ' + FORMAT([DateValue],'yyyy-MM-dd')
FROM EmailTable
WHERE ID = r.ID AND EmailType = 1
FOR XML PATH(''),TYPE
).value('(./text())[1]','NVARCHAR(MAX)'),
1,2,'')
工作原理
以x
作为元素名执行最里面的查询:
SELECT ', ' + format(DateValue,'yyyy-MM-dd')
FROM EmailTable
WHERE year=2019 and Day<5 and month=1
FOR XML PATH('x'),TYPE
会返回:
<x>, 2019-01-01</x>
<x>, 2019-01-02</x>
<x>, 2019-01-03</x>
<x>, 2019-01-04</x>
通过指定空字符串作为元素,我们得到:
, 2019-01-01, 2019-01-02, 2019-01-03, 2019-01-04
这仍然是一个 XML 值,其内部文本是我们想要的字符串。我们需要使用.value('(./text())[1]','nvarchar(max)')
提取它:
select ( SELECT ', ' + format(DateValue,'yyyy-MM-dd')
FROM EmailTable
WHERE year=2019 and Day<5 and month=1
FOR XML PATH(''),TYPE
).value('(./text())[1]','nvarchar(max)')
之后,我们需要删除前导分隔符,在这种情况下,两个字符 . T-SQL doesn't have a
REMOVEstring function and
SUBSTRINGneeds a length.
STUFF` 删除在附加一个指定数量的字符之前新字符串,因此它可用于从开头删除文本。
【讨论】:
以上是关于将 STUFF 与 DATE 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
不能将 $match 与 mongoose 和聚合框架一起使用
不能将 $match 与 mongoose 和聚合框架一起使用