【问题标题】:Multiple Substring Charindex多子串字符索引
【发布时间】:2021-02-24 07:43:44
【问题描述】:

我正在尝试从列中提取字符串以显示哪些是 FROM 表和 JOIN 表。完整的字符串由一个 FROM 表和多个 JOIN 表组成。这是一个字符串示例:

FROM [TABLEOWNER] .[load_XT_Customer_test] load_XT_Customer_test
INNER JOIN [TABLEOWNER].[load_xt_orders_test] load_xt_orders_test ON load_xt_customer_test.customer_id=load_xt_orders_test.customer_id
INNER JOIN [TABLEOWNER].[load_XT_Orders] load_XT_Orders ON 
load_xt_customer_test.customer_id=load_xt_orders.customer_id
INNER JOIN [TABLEOWNER].[load_xt_order_details_test] load_xt_order_details_test
ON load_xt_customer_test.customer_id=load_xt_order_details_test.customer_id  

我的问题是没有唯一的字符来分隔字符串,如何动态提取单连接表?

我测试过:

SELECT st_where 
        ,SUBSTRING(st_where 
       ,CHARINDEX('] ',st_where,1)+1 
       ,ABS(CHARINDEX(' ',st_where,CHARINDEX('] ',st_where,1)+1) 
-CHARINDEX(']',st_where,1)-1))
AS FromTable
       ,SUBSTRING(st_where 
       ,CHARINDEX('JOIN [TABLEOWNER].[',st_where,1)+19 
       ,ABS(CHARINDEX(' ',st_where,CHARINDEX('JOIN [TABLEOWNER].[',st_where,1)+19) 
       -CHARINDEX('JOIN [TABLEOWNER].[',st_where,1)-20))
AS JoinTable
,SUBSTRING(st_where 
       ,CHARINDEX('=',st_where,1)+59
       ,ABS(CHARINDEX(' ',st_where,CHARINDEX('=',st_where,1)+59) 
       -CHARINDEX('=',st_where,1)-60))
AS JoinTable2

【问题讨论】:

  • 我不明白你在这里问什么。示例数据和预期结果将帮助我们在这里为您提供帮助。我也非常推荐使用别名,它会让你的查询更加简洁。
  • 简化问题,向我们展示一些示例表数据和预期结果 - 全部为格式化文本(无图像)。 minimal reproducible example
  • 数据可以来自所有这些表,返回的列将是您在 SELECT 语句中指定的任何内容。来自不同表的列将保持独立(除非您使用 COALESCE 或类似的)。如果您需要指定哪些列在哪个表中,那么您可以在输出中重命名它们,例如SELECT load_XT_Customer_test.ColName as [Table_1_ColName] FROM load_XT_Customer_test
  • 您是否尝试通过 SQL 对另一个 SQL 语句进行字符串操作?

标签: sql-server tsql join substring charindex


【解决方案1】:

这应该让你开始:

DECLARE @st_where nvarchar(max) =
N'
FROM [TABLEOWNER] .[load_XT_Customer_test] load_XT_Customer_test
INNER JOIN [TABLEOWNER].[load_xt_orders_test] load_xt_orders_test ON load_xt_customer_test.customer_id=load_xt_orders_test.customer_id
INNER JOIN [TABLEOWNER].[load_XT_Orders] load_XT_Orders ON 
load_xt_customer_test.customer_id=load_xt_orders.customer_id
INNER JOIN [TABLEOWNER].[load_xt_order_details_test] load_xt_order_details_test
ON load_xt_customer_test.customer_id=load_xt_order_details_test.customer_id
';

SELECT
    TableName =
        SUBSTRING
        (
            SS.[value], 
            CharStart.pos + 1, 
            CharEnd.pos - CharStart.pos + 1
        )
FROM STRING_SPLIT
(
    -- Replace delimiter phrase with a single character
    -- so we can use STRING_SPLIT
    -- or use a more general string splitter
    REPLACE(@st_where, N'INNER JOIN', NCHAR(256)), 
    NCHAR(256)
) AS SS
CROSS APPLY 
(
    VALUES
    (
        -- Find the start of the table name
        CHARINDEX(N'.[', SS.[value], 1)
    )
) AS CharStart (pos)
CROSS APPLY 
(
    VALUES
    (
        -- Find the end of the table name
        CHARINDEX(N']', SS.[value], CharStart.pos)
    )
) AS CharEnd (pos);

db<>fiddle demo

一般的想法是在短语“INNER JOIN”上拆分输入字符串,然后使用“.[”和“]”作为分隔符定位表名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多