You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

替换PARSENAME实现多段|分隔字符串的SQL关联查询方案求助

解决TranReference多分段字符串的精准拆分与关联问题

推荐:用OPENJSON实现精准拆分(SQL Server 2016及以上)

OPENJSON能把分隔字符串转成带顺序的键值对,完美替代受4段限制的PARSENAME。假设你要从TranReference(格式如xxx|员工号|工单头Seq|工单行Seq|xxx)里提取第2段做EmployeeNum、第3段做LaborHedSeq、第4段做LaborDtlSeq,关联LaborDtl表的代码如下:

SELECT 
    t.*,
    ld.*
FROM 你的业务表 t
CROSS APPLY (
    -- 把|分隔的字符串转成JSON数组,解析出每一段和对应序号
    SELECT
        MAX(CASE WHEN SegmentIndex = 2 THEN value END) AS EmployeeNum,
        MAX(CASE WHEN SegmentIndex = 3 THEN value END) AS LaborHedSeq,
        MAX(CASE WHEN SegmentIndex = 4 THEN value END) AS LaborDtlSeq
    FROM (
        SELECT 
            value,
            ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS SegmentIndex
        FROM OPENJSON('["' + REPLACE(t.TranReference, '|', '","') + '"]')
    ) AS Segments
) AS ExtractedValues
-- 关联LaborDtl表
JOIN LaborDtl ld ON 
    ld.EmployeeNum = ExtractedValues.EmployeeNum
    AND ld.LaborHedSeq = ExtractedValues.LaborHedSeq
    AND ld.LaborDtlSeq = ExtractedValues.LaborDtlSeq

SQL Server 2022+专属:带序号的STRING_SPLIT

如果你的SQL Server是2022或更高版本,直接用STRING_SPLIT的第三个参数启用序号功能,代码更简洁:

SELECT 
    t.*,
    ld.*
FROM 你的业务表 t
CROSS APPLY (
    SELECT
        MAX(CASE WHEN ordinal = 2 THEN value END) AS EmployeeNum,
        MAX(CASE WHEN ordinal = 3 THEN value END) AS LaborHedSeq,
        MAX(CASE WHEN ordinal = 4 THEN value END) AS LaborDtlSeq
    FROM STRING_SPLIT(t.TranReference, '|', 1) -- 第三个参数1开启序号返回
) AS ExtractedValues
JOIN LaborDtl ld ON 
    ld.EmployeeNum = ExtractedValues.EmployeeNum
    AND ld.LaborHedSeq = ExtractedValues.LaborHedSeq
    AND ld.LaborDtlSeq = ExtractedValues.LaborDtlSeq

低版本兼容:自定义带序号的拆分函数

如果用的是SQL Server 2016以下版本,先创建一个能返回分段序号的自定义函数:

CREATE FUNCTION dbo.SplitStringWithOrdinal(
    @InputString NVARCHAR(MAX),
    @Delimiter NVARCHAR(10)
)
RETURNS TABLE 
AS
RETURN (
    WITH SplitCTE AS (
        SELECT
            CAST(0 AS BIGINT) AS StartPos,
            CHARINDEX(@Delimiter, @InputString) AS EndPos,
            1 AS Ordinal
        UNION ALL
        SELECT
            EndPos + LEN(@Delimiter),
            CHARINDEX(@Delimiter, @InputString, EndPos + LEN(@Delimiter)),
            Ordinal + 1
        FROM SplitCTE
        WHERE EndPos > 0
    )
    SELECT
        Ordinal,
        SUBSTRING(
            @InputString,
            StartPos + CASE WHEN StartPos = 0 THEN 0 ELSE 1 END,
            CASE WHEN EndPos = 0 THEN LEN(@InputString) - StartPos ELSE EndPos - StartPos - LEN(@Delimiter) + 1 END
        ) AS Value
    FROM SplitCTE
    WHERE StartPos < LEN(@InputString)
)
GO

然后用这个函数拆分并关联:

SELECT 
    t.*,
    ld.*
FROM 你的业务表 t
CROSS APPLY (
    SELECT
        MAX(CASE WHEN Ordinal = 2 THEN Value END) AS EmployeeNum,
        MAX(CASE WHEN Ordinal = 3 THEN Value END) AS LaborHedSeq,
        MAX(CASE WHEN Ordinal = 4 THEN Value END) AS LaborDtlSeq
    FROM dbo.SplitStringWithOrdinal(t.TranReference, '|')
) AS ExtractedValues
JOIN LaborDtl ld ON 
    ld.EmployeeNum = ExtractedValues.EmployeeNum
    AND ld.LaborHedSeq = ExtractedValues.LaborHedSeq
    AND ld.LaborDtlSeq = ExtractedValues.LaborDtlSeq

内容的提问来源于stack exchange,提问作者jdixon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:53:16