TSQL一个字符序列必须紧跟另一个

时间:2018-11-28 07:34:09

标签: tsql case

第一次提问,但我想我会看看是否有人清楚如何执行此操作。谢谢。

我有一个视图,其中包含有关医院程序的信息。通常使用名称和日期字段,然后是一个包含所有关联过程的字段,这些过程被串联到单个字段中,并用竖线分隔。程序代码通常为4位数字,代表完成的每个程序。

例如名称,出生日期,| W822 | W833 | Z846 | Z942 |||||||||||||||||||||||||||||||||||| < / p>

以W833,W834,W835开头的过程代码应始终跟随一个站点代码(在执行过程的主体上执行该操作)Z00-Z93或Z95-Z99

但是,它的Y代码可能介于W代码和Z代码之间(Y282,...)

在Y *代码之后可能还会有一个Z94 *

如何构造查询以查找不正确的过程。

我认为最好的方法是使用复杂的CASE语句。还有其他建议吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

如果您只想获取过程代码顺序错误的行,则可以使用函数来验证过程代码:

CREATE FUNCTION fn_ValidateOrder ( @InputString NVARCHAR(MAX), @Delimiter NCHAR(1))
RETURNS BIT 
AS 
BEGIN

    DECLARE @Valid BIT = 0, @Errors INT
    /* Table to hold splitt string */
    DECLARE @T TABLE (id INT IDENTITY(1,1),Val NVARCHAR(128) NULL)
    INSERT INTO @T
        SELECT value FROM STRING_SPLIT(@InputString,@Delimiter) WHERE value != ''
    /* Validated order */
    ;WITH rn AS (
        SELECT
            ROW_NUMBER() OVER (ORDER BY val) AS rn
            ,id,
            val
        FROM @T 
    )
    /* Count errors */
    SELECT @Errors=SUM(CASE WHEN id IS NOT NULL THEN 1 ELSE 0 END) FROM rn WHERE id!=rn
    /* Set return value */
    IF @Errors>0
        SET @Valid=0
    ELSE
        SET @Valid=1

    RETURN @Valid
END

我使用以下测试数据进行了验证:

/* Test Data*/
DECLARE @data TABLE (DateOfBirth VARCHAR(6),ProcedureCode VARCHAR(MAX))

INSERT INTO @data (DateOfBirth,ProcedureCode)
VALUES ('010176','|W822|W833|Z846|Z942|||||||||||||||||||||||||||||||||||||'),
('120176','|W822|Z282|W833|Z846|Z942|||||||||||||||||||||||||||||||||||||')

/* Validated test data */
SELECT
    DateOfBirth,
    dbo.fn_ValidateOrder(ProcedureCode,'|') AS ValidOrder,
    ProcedureCode
FROM @data
WHERE dbo.fn_ValidateOrder(ProcedureCode,'|') = 0

请注意,这仅适用于SQL 2016及更高版本,因为该函数使用SPLIT_STRING。