交叉应用使用的子查询不是 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 BYORDER 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() 调用的结果是包含 keyvaluetype 列的 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