对于这个拆分字符串函数,Aaron推荐这里,我有一个问题。
使用它,您可以在两个斜杠之间提取信息。现在,如果我不仅想提取一段像servername这样的信息,而且还想提取另一段信息,比如一周中的一天。我要如何重写代码才能在一个结果集中获得这些信息?
这是我的数据样本
E:\BaseData\RUK\HPP_Conversion_Detail\hpp_conversion_detail_report_2015_11_02.csv
E:\BaseData\RUK\Manual_Review\manual_review_report_2015_11_01.csv
E:\BaseData\RUK\Disputes\dispute_report_2015_11_01.csv
E:\BaseData\RSE\HPP_Conversion_Detail\hpp_conversion_detail_report_2015_11_02.csv
E:\BaseData\RSE\Manual_Review\manual_review_report_2015_11_01.csv
E:\BaseData\RSE\Disputes\dispute_report_2015_11_01.csv我对第二次、第三次和第三次和第四次之间的一切都感兴趣。杰夫的建议是个好主意。然后我会一排排地得到结果。是否有可能在其他列中返回结果?
谢谢!
发布于 2015-11-03 13:53:10
使用Aaron推荐的这里。
CREATE FUNCTION dbo.SplitStringsOrdered
(
@List NVARCHAR(2000),
@Delimiter NVARCHAR(32)
)
RETURNS TABLE
AS
RETURN
(
SELECT rn = ROW_NUMBER() OVER (ORDER BY Number), Item
FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)))
FROM (SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects) AS n(Number)
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
) AS y);和你的例子数据
CREATE TABLE #x
(filepath NVARCHAR(2000));
INSERT #x VALUES
('E:\BaseData\RUK\HPP_Conversion_Detail\hpp_conversion_detail_report_2015_11_02.csv'),
('E:\BaseData\RUK\Manual_Review\manual_review_report_2015_11_01.csv'),
('E:\BaseData\RUK\Disputes\dispute_report_2015_11_01.csv'),
('E:\BaseData\RSE\HPP_Conversion_Detail\hpp_conversion_detail_report_2015_11_02.csv'),
('E:\BaseData\RSE\Manual_Review\manual_review_report_2015_11_01.csv'),
('E:\BaseData\RSE\Disputes\dispute_report_2015_11_01.csv')然后你就可以运行这样的
SELECT * FROM #x x
CROSS APPLY dbo.SplitStringsOrdered(x.filepath, '\') sso
WHERE sso.rn = 3把第三部分拿出来。
有几种方法可以获得多个部分。您可以从末尾删除WHERE sso.rn =3,但是数据会分散在许多行上,而这些行可能对您不起作用。
类似这样的东西可能适用于您使用子查询。
SELECT *
, Part3 = (SELECT sso.Item FROM dbo.SplitStringsOrdered(x.filepath, '\') sso
WHERE sso.rn = 3)
, Part5 = (SELECT sso.Item FROM dbo.SplitStringsOrdered(x.filepath, '\') sso
WHERE sso.rn = 5)
FROM #x x高亮代码上面的警告错误地认为\转义它后面的单引号,这实际上不是SSMS/server中的情况,除非您请求该行为。
如果你想要每件事都是一个黑客使用might可能是最好的你。
;
WITH splits
AS (
SELECT x.filepath
, sso.rn
, sso.Item
FROM #x x
CROSS APPLY dbo.SplitStringsOrdered(x.filepath, '\') sso
)
SELECT *
FROM
( SELECT splits.filepath
, splits.rn
, splits.Item
FROM splits ) AS src
PIVOT ( MIN(Item)
FOR rn IN ([1],[2],[3],[4],[5])
) AS pvt但这看起来有点疯狂,实际上并没有看起来那么灵活或有用,而且总体上的MIN是丑陋的。
因此,您可以在不需要支点攻击和更多子查询的情况下,将两者混合起来。
;WITH splits
AS (
SELECT x.filepath
, sso.rn
, sso.Item
FROM #x x
CROSS APPLY dbo.SplitStringsOrdered(x.filepath, '\') sso
)
SELECT x.filepath
, (
SELECT s.Item FROM splits s WHERE s.rn = 2 AND s.filepath = x.filepath
)
, (
SELECT s.Item FROM splits s WHERE s.rn = 3 AND s.filepath = x.filepath
)
, (
SELECT s.Item
FROM splits s
WHERE s.rn = (
SELECT MAX (splits.rn) FROM splits
)
AND s.filepath = x.filepath
)
FROM #x x发布于 2015-11-02 19:33:50
尝试执行常规拆分,获得类似于20151002SERVER1的字符串。然后,只需将CONVERT(date,LEFT(Item,8),112)和STUFF(Item,1,8,'')作为您的日期和服务器名称即可。
https://dba.stackexchange.com/questions/119813
复制相似问题