将特定行的连接值插入Transact SQL中的临时表

问题描述 投票:1回答:1

我正在将我们旧的平面数据库中运行的导出脚本重写为新的规范化结构。在过去,我们有一个名为Case的表,其中有三列用于所有者名称信息 - Ownername1,Ownername2和Ownername3。现在,我们有零对多的债务人,而不是一行最多有三个所有者,我们每个所有者都有一排。我不得不将其按到导出中,该导出将用于客户端正在使用的Excel电子表格中,但我必须“愚蠢”地将结构装回到该平面结构中。我需要获取前三行所有者的名称并连接名字和姓氏。我一直在玩(SELECT ROW_NUMBER()OVER它看起来像解决方案,但我不能让它适用于我的情况。我不仅需要连接名字和姓氏,但我还需要合并它们是空字符串并将结果插入临时表。在我们的系统中,一个案例可以有多个债务人。主债务人的DEIsPrimary值为1. CApKey是案例的关键值。

如果我这样做,使用单个列我得到预期的结果:

(SELECT DEPhone FROM 
(SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC) 
AS rownumber, DEPhone FROM Debtor d WHERE d.CApKey = 151490 AND d.DEIsPrimary <> 1) 
AS foo WHERE rownumber = 1)

这将返回有效的电话号码。当我尝试扩展它时,使用如下的连接名称:

(SELECT DEFirstName + ' ' + DELastName FROM 
(SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC) 
AS rownumber, DEFIrstName + ' ' + DELastName FROM Debtor d WHERE d.CApKey = 151490 AND d.DEIsPrimary <> 1) 
AS foo WHERE rownumber = 1)

我得到两个错误:我被告知DEFirstName和DELastName是无效的列名,我还被告知没有为foo的第2列指定列。在这种情况下连接是不可能的?我试过没有运气的名字别名。这几乎是我认为我需要的,但正如你所看到的,我还没有得到COALESCE。这是我最初的尝试:

UPDATE #temp SET OwnerNameTwo = (SELECT DEFirstName + ' ' + DELastName FROM 
    (SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC) 
    AS rownumber, DEFirstName + ' ' + DELastName
    FROM Debtor d WHERE d.CApKey = #temp.CApKey AND d.DEIsPrimary <> 1) 
    AS foo WHERE rownumber = 1)

提前感谢您花时间帮助我。我非常感谢任何和所有的反馈!

sql sql-server tsql concatenation row-number
1个回答
0
投票

构建派生表时,除非它们出现在派生表的最外层查询中的SELECT之后的列表中,否则无法直接访问基础表的列。

所以

SELECT a
       FROM (SELECT a
                    FROM t) x;

工作,而

SELECT b
       FROM (SELECT a
                    FROM t) x;

即使b中有一列t也不起作用。

但实际上这更进一步。您可以从最外面的查询中选择任何列表达式,如

SELECT y
       FROM (SELECT a + b y
                    FROM t) x;

但是你需要为表达式给出的每个列命名。虽然有些系统可能会自动为表达式生成可用的别名,但有些系统却没有,即使它们也这样做,这些别名通常对读写起来并不“好”。所以使用显式别名。

你在这里做的不是重复表达,希望能给你各自的价值。即

SELECT a + b
       FROM (SELECT a + b
                    FROM t) x;

不行。

但最后一个问题是你做的。

因此,要么将串联移动到外部查询,只需列出内部查询中的列

UPDATE #temp
       SET ownernametwo = (SELECT defirstname + ' ' + delastname
                                  FROM (SELECT row_number() OVER (ORDER BY depkey ASC) rownumber,
                                               defirstname,
                                               delastname
                                               FROM debtor d
                                               WHERE d.capkey = #temp.capkey
                                                     AND d.deisprimary <> 1) foo
                                       WHERE rownumber = 1);

或者在内部查询中保留连接别名为外部查询中的别名:

UPDATE #temp
       SET ownernametwo = (SELECT fullname
                                  FROM (SELECT row_number() OVER (ORDER BY depkey ASC) rownumber,
                                               defirstname + ' ' + delastname fullname
                                               FROM debtor d
                                               WHERE d.capkey = #temp.capkey
                                                     AND d.deisprimary <> 1) foo
                                       WHERE rownumber = 1);
© www.soinside.com 2019 - 2024. All rights reserved.