我们如何在 SQL 中的一个 CTE 中做到这一点 [已关闭]

How can we do this in one CTE in SQL [closed]

提问人:SilverFish 提问时间:6/28/2023 最后编辑:Dale KSilverFish 更新时间:6/28/2023 访问量:59

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

5个月前关闭。

我在列中有数据作为 (LastName, FirstName (EmpId)) 我需要 LastName 和 FirstName 在单独的列中。我创建了 2 个 CTE。我无法用一个 CTE 实现相同的目标。另外,如果有更好的方法可以实现这一点,请告知

IF OBJECT_ID('tempdb..#tempMyTable') IS NOT NULL
    DROP TABLE #tempMyTable

CREATE TABLE #tempMyTable(
    REPORT_TO varchar(25) not null
)
INSERT INTO #tempMyTable
VALUES
('MILLER, BEN (BMR09876)'),
('LON, JOHN (JLON45098)'),
('WILSON, MARY (MWN2345)');
    
WITH CTE_Name AS (
    SELECT [REPORT_TO], LEFT([REPORT_TO], Charindex(',', [REPORT_TO]) -1) as LNAME,
    RIGHT([REPORT_TO], LEN([REPORT_TO]) - CHARINDEX(',', [REPORT_TO])) as FNAME
    FROM #tempMyTable
), CTE_FNAME AS (
    SELECT Report_To, LName, LEFT(FName, CHARINDEX('(', FName)-2) as FName
    FROM CTE_Name
)
SELECT *
FROM CTE_FNAME
sql sql-server 公用表表达式 字符索引

评论

0赞 Jorge Campos 6/28/2023
请标记您正在使用的 RDBM。
0赞 Dale K 6/28/2023
请显示您想要的结果。

答:

0赞 David Browne - Microsoft 6/28/2023 #1

您可以将临时表替换为 SELECT ...CTE 中的值,例如:

with cte_t
as
(

  select * from (values ('MILLER, BEN (BMR09876)'),
                        ('LON, JOHN (JLON45098)'), 
                        ('WILSON, MARY (MWN2345)') ) as X(REPORT_TO)
), CTE_Name as 
(
  SELECT  [REPORT_TO], LEFT([REPORT_TO], Charindex(',', [REPORT_TO]) -1) as LNAME,
  RIGHT([REPORT_TO], LEN([REPORT_TO]) - CHARINDEX(',', [REPORT_TO])) as FNAME
  FROM cte_t
), CTE_FNAME as
(
  SELECT Report_To, LName, LEFT(FName,  CHARINDEX('(', FName)-2) as FName
  FROM CTE_Name
)
select * from CTE_FNAME

评论

0赞 SilverFish 6/28/2023
临时表仅用于演示。不过我有一张物理桌子。我需要从一个表中选择列数,然后在另一个表中插入。REPORT_TO 是其中一列
1赞 Charlieface 6/28/2023 #2

您可以使用一系列 来分阶段计算事物,而无需使用 CTE。CROSS APPLY

SELECT
  t.Report_To,
  v2.LName,
  LEFT(FName, NULLIF(CHARINDEX('(', FName), 0) - 2) as FName
FROM #tempMyTable t
CROSS APPLY (
    SELECT
      NULLIF(CHARINDEX(',', t.REPORT_TO), 0)
) v1
CROSS APPLY (
    SELECT
      LEFT(t.REPORT_TO, v1.comma -1) as LNAME,
      RIGHT(t.REPORT_TO, LEN(t.REPORT_TO) - v1.comma) as FNAME
) v2;

请注意,在找不到值的情况下使用 to prevent error。NULLIFCHARINDEX

评论

0赞 SilverFish 6/28/2023
查询对我不起作用
0赞 Dale K 6/28/2023
@SilverFish “不起作用”是什么意思?语法错误?没有返回所需的结果?
0赞 Charlieface 6/28/2023
@SilverFish对不起,现在应该修复输入错误