交叉应用使用的子查询不是 Return 结果
Cross Apply used Sub Query not Return Result
我想从 deviceinfo
列中提取版本数据。为此,我正在使用 Cross Apply.
Order
----------------------------------
OrdeId DeviceInfo
----------------------------------
10 PageSize|BGColor|3000|V1.0
11 PageSize|BGColor|3000|V2.0
12 PageSize|BGColor|3000|V3.0
----------------------------------
我使用了下面的查询
Select * From
(
Select OrderId, DeviceInfo, Value, ROW_NUMBER() Over(Partition By DeviceInfo Order By OrderId Asc) As Rn
FROM Order As Ord
Cross Apply STRING_SPLIT(DeviceInfo, '|') As Di
Where IsNull(Ord.DeviceInfo,'') != '' And OrderId='10'
)A Where A.Rn=4 And A.OrderId='10'
我得到了结果。
OrderId DeviceInfo Value Rn
------------------------------------------------
10 PageSize|BGColor|3000|V1.0 V1.0 4
如果我在子查询中使用不带 orderid 过滤器的查询,我得到一个空结果。
Select * From
(
Select OrderId, DeviceInfo, Value, ROW_NUMBER() Over(Partition By DeviceInfo Order By OrderId Asc) As Rn
FROM Order As Ord
Cross Apply STRING_SPLIT(DeviceInfo, '|') As Di
Where IsNull(Ord.DeviceInfo,'') != ''
)A Where A.Rn=4 And A.OrderId='10'
请帮我解决这个问题
对意外结果的可能解释是以下问题的组合:
- 在
ROW_NUMBER()
函数调用中错误地使用了 PARTITION BY
和 ORDER BY
子句。 ROW_NUMBER() Over (Partition By DeviceInfo Order By OrderId Asc)
以随机和意外的顺序对行进行编号。
- 使用
STRING_SPLIT()
按位置提取子字符串是一个棘手的方法。正如文档中的 mentioned 一样, 输出行可以按任何顺序排列 并且 不能保证顺序与输入中子字符串的顺序相匹配字符串.
在您的情况下(如果您想按位置提取子字符串),您可以尝试使用基于 JSON 的方法来解析 DeviceInfo
列。您需要将数据转换为有效的 JSON 数组(PageSize|BGColor|3000|V1.0
转换为 ["PageSize","BGColor","3000","V1.0"]
)并使用 OPENJSON()
解析此数组。 OPENJSON()
调用的结果是包含 key
、value
和 type
列的 table,并且 key
列包含从 0 开始的索引指定数组中的元素。
Table:
CREATE TABLE [Order] (
OrderId int,
DeviceInfo varchar(1000)
)
INSERT INTO [Order] (OrderId, DeviceInfo)
VALUES
(10, 'PageSize|BGColor|3000|V1.0'),
(11, 'PageSize|BGColor|3000|V2.0'),
(12, 'PageSize|BGColor|3000|V3.0')
声明:
SELECT OrderId, DeviceInfo, [Value]
FROM [Order] AS o
CROSS APPLY OPENJSON(CONCAT('["', REPLACE(o.DeviceInfo, '|', '","'), '"]')) AS j
WHERE o.OrderId = 10 AND j.[key] = '3'
结果:
OrderId DeviceInfo Value
----------------------------------------
10 PageSize|BGColor|3000|V1.0 V1.0
我想从 deviceinfo
列中提取版本数据。为此,我正在使用 Cross Apply.
Order
----------------------------------
OrdeId DeviceInfo
----------------------------------
10 PageSize|BGColor|3000|V1.0
11 PageSize|BGColor|3000|V2.0
12 PageSize|BGColor|3000|V3.0
----------------------------------
我使用了下面的查询
Select * From
(
Select OrderId, DeviceInfo, Value, ROW_NUMBER() Over(Partition By DeviceInfo Order By OrderId Asc) As Rn
FROM Order As Ord
Cross Apply STRING_SPLIT(DeviceInfo, '|') As Di
Where IsNull(Ord.DeviceInfo,'') != '' And OrderId='10'
)A Where A.Rn=4 And A.OrderId='10'
我得到了结果。
OrderId DeviceInfo Value Rn
------------------------------------------------
10 PageSize|BGColor|3000|V1.0 V1.0 4
如果我在子查询中使用不带 orderid 过滤器的查询,我得到一个空结果。
Select * From
(
Select OrderId, DeviceInfo, Value, ROW_NUMBER() Over(Partition By DeviceInfo Order By OrderId Asc) As Rn
FROM Order As Ord
Cross Apply STRING_SPLIT(DeviceInfo, '|') As Di
Where IsNull(Ord.DeviceInfo,'') != ''
)A Where A.Rn=4 And A.OrderId='10'
请帮我解决这个问题
对意外结果的可能解释是以下问题的组合:
- 在
ROW_NUMBER()
函数调用中错误地使用了PARTITION BY
和ORDER BY
子句。ROW_NUMBER() Over (Partition By DeviceInfo Order By OrderId Asc)
以随机和意外的顺序对行进行编号。 - 使用
STRING_SPLIT()
按位置提取子字符串是一个棘手的方法。正如文档中的 mentioned 一样, 输出行可以按任何顺序排列 并且 不能保证顺序与输入中子字符串的顺序相匹配字符串.
在您的情况下(如果您想按位置提取子字符串),您可以尝试使用基于 JSON 的方法来解析 DeviceInfo
列。您需要将数据转换为有效的 JSON 数组(PageSize|BGColor|3000|V1.0
转换为 ["PageSize","BGColor","3000","V1.0"]
)并使用 OPENJSON()
解析此数组。 OPENJSON()
调用的结果是包含 key
、value
和 type
列的 table,并且 key
列包含从 0 开始的索引指定数组中的元素。
Table:
CREATE TABLE [Order] (
OrderId int,
DeviceInfo varchar(1000)
)
INSERT INTO [Order] (OrderId, DeviceInfo)
VALUES
(10, 'PageSize|BGColor|3000|V1.0'),
(11, 'PageSize|BGColor|3000|V2.0'),
(12, 'PageSize|BGColor|3000|V3.0')
声明:
SELECT OrderId, DeviceInfo, [Value]
FROM [Order] AS o
CROSS APPLY OPENJSON(CONCAT('["', REPLACE(o.DeviceInfo, '|', '","'), '"]')) AS j
WHERE o.OrderId = 10 AND j.[key] = '3'
结果:
OrderId DeviceInfo Value
----------------------------------------
10 PageSize|BGColor|3000|V1.0 V1.0