SQL 语法:从数组中选择自定义字符串未正确选择

SQL Syntax Select Custom String from an Array not selecting Correctly

提问人:Glen Owen 提问时间:11/9/2023 最后编辑:Dale KGlen Owen 更新时间:11/10/2023 访问量:83

问:

问题:

我正在尝试从多个表(表 A 和 B)中进行选择,但这主要是关于我从表 B 中选择的唯一列。此列中的值包含字符串的 Array。

目标是摆脱任何 [],然后查看字符串。有两种主要类型的字符串,一种以“需要一些文本”开头,另一种以相同的“需要一些文本”开头,后跟逗号和进一步的文本,其他类型的字符串包含随机文本,不以“需要一些文本”开头。

  • “需要一些文字”
  • “需要一些文本,其他”
  • “需要一些文本,额外的文本”
  • “需要一些文本,额外 - 文本,必填”
  • “今天是下雨天”
  • “特别热”

需要什么:

对于字符串不以“需要一些文本”开头的条件,只需返回文本值,对于其他条件,返回逗号 (,) 后面的值,同时忽略“需要一些文本”,因此输出将如下所示:

预期结果:

  • “其他”
  • “额外文本”
  • “额外 - 文本,必需”
  • “今天是下雨天”
  • “特别热”

我使用了以下 SQL 代码,它删除了 [ 和 ],但它总是让我回到“需要一些文本,其他”而不仅仅是“其他”

SELECT
    col1, col2, ..., col10,
    CASE
        WHEN CHARINDEX('[', cier.if_text_is_required) > 0
        THEN REPLACE(REPLACE(cier.if_text_is_required, '[', ''), ']', '')
        WHEN CHARINDEX('some text needed,', cier.if_text_is_required) > 0
        THEN
            CASE
                WHEN CHARINDEX(',', cier.if_text_is_required, CHARINDEX('some text needed,', cier.if_text_is_required) + LEN('some text needed,')) > 0
                THEN LTRIM(SUBSTRING(cier.if_text_is_required, CHARINDEX(',', cier.if_text_is_required, CHARINDEX('some text needed,', cier.if_text_is_required) + LEN('some text needed,')) + 2, LEN(cier.if_text_is_required)))
                ELSE cier.if_text_is_required
            END
        ELSE cier.if_text_is_required
    END AS if_text_is_required

FROM TableA
LEFT JOIN (
    SELECT id, if_text_is_required, ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC, rn_id DESC) AS rn
    FROM TableB
    WHERE if_text_is_required IS NOT NULL
) AS cier ON TableA.id = cier.id AND cier.rn = 1

我可以摆脱 [ 和 ],但是,当字符串包含“需要一些文本”时,我无法仅选择逗号后面的字符串。

有人可以发现上述 SQL 的任何问题并可以帮助我吗?感谢所有协助。

sql-server 左联接 azure-synapse charindex 子查询

评论

1赞 Stu 11/9/2023
请显示实际样品数据和实际期望结果
0赞 Xedni 11/9/2023
嗨,格伦,欢迎来到堆栈溢出。我看到你提供了几个你希望看到的单词列表,但如果你包括一些实际数据会很有帮助。如果方括号的修剪是您问题的相关部分,请包括该数据。坦率地说,我不认为这真的是问题的一部分,就好像你已经设法修剪了你的琴弦,那么根据定义,你对它们没有问题。但无论哪种方式,拥有真实的输入数据和预期结果对于我们能够有效地为您提供帮助至关重要。

答:

0赞 Aneema 11/9/2023 #1
SELECT 
      A.*,
      CASE 
          WHEN B.YourColumn LIKE 'some text needed%' 

          THEN STUFF(B.YourColumn, 1, CHARINDEX(',', B.YourColumn + ','), '')
          ELSE REPLACE(REPLACE(B.YourColumn, '[', ''), ']', '')
      END as manipulated_column
    FROM 
      TableA AS A
    JOIN 
      TableB AS B 
      ON A.JoinColumn = B.JoinColumn
  • STUFF():此函数用于删除字符串的一部分并将其替换为另一个字符串。
  • CHARINDEX():这将查找另一个字符串中第一个字符串出现的索引。
  • REPLACE():使用两次来删除“[”和“]”

评论

0赞 Glen Owen 11/9/2023
感谢您的回答,但这不会摆脱左连接(SELECT From?我需要有这个逻辑,或者这个解决方案是否适用于现有的 LEFT JOIN SELECT?
0赞 Aneema 11/9/2023
您在问题中提到了两个表:表 A 和表 B(假设您需要将它们放在一起)。如果不需要合并它们,则联接将毫无用处。
0赞 Glen Owen 11/9/2023
此解决方案似乎无法按预期工作。首先,它用空格替换所有“需要一些文本”,而在这种情况下,我们只需要返回“需要一些文本”。其次,这段代码唯一要做的就是去掉'['和']'。我们需要返回原始字符串,除非 SQL 遇到“一些文本需要,然后是一些更多的文本 - 额外的文本”。在这种情况下,我们只需要保留逗号(,)后面的字符串的第二部分,在这种情况下,这将是“更多的文本”。对于所有其他 NON“更多文本”情况,我们需要返回原始字符串
0赞 Glen Owen 11/9/2023
不确定这是否有帮助,但我注意到方括号只存在于“[需要一些文本,后面跟着 - 一些其他文本]”的情况下,并且不出现在任何其他字符串周围。感谢您在此期间的帮助
0赞 Xedni 11/9/2023 #2

以下是我的做法。我在这里创建了自己的数据集,因为问题中没有提供任何数据集,并删除了与问题无关的连接和表达式。从表面上看,您的问题是关于设置字符串格式。因此,我将从以下数据开始:

drop table if exists #data
select String
into #data
from
(
    values
    ('[some text needed]'),
    ('[some text needed, other]'),
    ('[some text needed, extra text]'),
    ('[some text needed, extra - text, required]'),
    ('[today is a rainy day]'),
    ('[Extra hot]')

) a (string)

同样,我认为方括号问题可能与这个问题无关紧要,因为你甚至说它不会给你带来任何问题。但既然你提到过,我就把它们留下来。

我要做的第一件事是去掉方括号。您可以使用该函数并提供要修剪的字符列表来执行此操作。在这种情况下,我选择修剪以去除括号和任何可能残留的空格。trim[]

首先,我将把这个特殊值“需要一些文本”分配给一个变量,这样我就不必重新输入它。

然后你只需要处理你的不同情况。由于您可以有一个字符串,该字符串只是“需要一些文本”,后面没有项目,因此我们将其视为特例,并将其输出值设置为空字符串。

另一种特殊情况是,当我们有“需要一些文本”后跟逗号和其他一些东西时。因此,我们将检查清理后的字符串是否以“需要一些文本”开头(注意逗号)。我喜欢通过使用该函数来处理它。当您需要从字符串开头删除一定数量的字符时,STUFF 非常有用。所以在这里,我删除了该逗号之前的所有字符,并添加了 2(一个是因为 stuff 函数需要下一个字符的索引,另一个是因为如果我只是接受它不会考虑逗号)。stufflen(@Slug)

当然,默认情况是只回显原始字符串。

declare @slug nvarchar(128) = 'some text needed'

select
    String,
    TrimmedString,
    case
        when TrimmedString = @slug then ''
        when TrimmedString like @Slug + ',%' then stuff(TrimmedString, 1, len(@Slug) + 2, '')
        else TrimmedString
    end
from #data
cross apply
(
   select TrimmedString = trim('[] ' from string)
) b

请注意,如果运行的 SQL Server 版本不支持 ,则只需将该函数调用替换为已使用的代码即可。如果您有权访问它,这只是一个快捷方式。TRIM

0赞 Glen Owen 11/9/2023 #3

将大小写 When 更改为“需要一些文本”(添加逗号)有助于处理问题并返回不带方括号的所有内容。

SELECT 
      A.*,
      CASE 
          WHEN B.YourColumn LIKE '

          THEN STUFF(B.YourColumn, 1, CHARINDEX(',', B.YourColumn + ','), '')
          ELSE REPLACE(REPLACE(B.YourColumn, '[', ''), ']', '')
      END as manipulated_column
    FROM 
      TableA AS A
    JOIN 
      TableB AS B 
      ON A.JoinColumn = B.JoinColum

但是,我无法仅选择逗号之后的脚本的第二部分。如果字符串有 2 个部分,用逗号分隔,我只想选择第一个逗号之后的所有内容,如果有多个逗号,则只能选择逗号后面的字符串,直到第三个逗号(不包括第三个逗号)。

希望它有助于解释这个问题