Sql server 无法使用CONCAT、COALESCE和ISNULL在SQL中表示空值

Sql server 无法使用CONCAT、COALESCE和ISNULL在SQL中表示空值,sql-server,sql-server-2017,Sql Server,Sql Server 2017,我有一个具有多个联接的查询,其中我希望将两列中的记录合并为一列。如果一列为空,那么我想显示一列值作为结果。我试过使用CONCAT、COALEASE和ISNULL,但没有成功。我错过了什么 我的目标是,创建一个列,其中包含s.Script作为原始和来自另一个表来自查询的组合。下面的查询运行,但抛出另一个表中的无效列名“Original”和无效列名“。当我尝试使用CONCAT、COALEASE或ISNULL时 SQL查询: SELECT DISTINCT c.Name AS CallC

我有一个具有多个联接的查询,其中我希望将两列中的记录合并为一列。如果一列为空,那么我想显示一列值作为结果。我试过使用
CONCAT
COALEASE
ISNULL
,但没有成功。我错过了什么

我的目标是,创建一个列,其中包含
s.Script作为原始
来自另一个表
来自查询的组合。下面的查询运行,但抛出另一个表中的
无效列名“Original”
无效列名“
。当我尝试使用
CONCAT
COALEASE
ISNULL

SQL查询:

SELECT DISTINCT
       c.Name AS CallCenter,
       LTRIM(RTRIM(s.Name)) Name,
       d.DNIS,
       s.ScriptId,
      s.Script AS Original,
      (
          SELECT TOP 5 CCSL.Line+'; ' 
          FROM CallCenterScriptLine CCSL
          WHERE CCSL.ScriptId = s.ScriptId
          ORDER BY ScriptLineId FOR XML PATH('')
       ) AS FromAnotherTable,
         --CONCAT(s.Script, SELECT TOP 5 CCSL.Line+'; ' FROM dbo.CallCenterScriptLine ccsl WHERE ccsl.ScriptId = s.ScriptId ORDER BY ccsl.ScriptLineId xml path(''))
         --CONCAT(Original, FromAnotherTable) AS Option1,
         --COALESCE(Original, '') + FromAnotherTable AS Option2,
         --ISNULL(Original, '') + FromAnotherTable AS Option3,,
       r.UnitName AS Store,
       r.UnitNumber
FROM CallCenterScript s WITH (NOLOCK)
     INNER JOIN CallCenterDNIS d WITH (NOLOCK) ON d.ScriptId = s.ScriptId
     INNER JOIN CallCenter c WITH (NOLOCK) ON c.Id = s.CallCenterId
     INNER JOIN CallCenterDNISRestaurant ccd WITH (NOLOCK) ON ccd.CallCenterDNISId = d.CallCenterDNISId
     INNER JOIN dbo.Restaurant r WITH (NOLOCK) ON r.RestaurantID = ccd.CallCenterRestaurantId
WHERE c.Id = 5
      AND (1 = 1)
      AND (s.IsDeleted = 0 OR s.IsDeleted IS NULL)
ORDER BY DNIS ASC;
SELECT DISTINCT
       c.Name AS CallCenter,
       LTRIM(RTRIM(s.Name)) Name,
       d.DNIS,
       s.ScriptId,
      s.Script AS Original,
      (
          SELECT TOP 5 ISNULL(CCSL.Line, '')+'; ' + ISNULL(s.Script, '')
          FROM CallCenterScriptLine CCSL
          WHERE CCSL.ScriptId = s.ScriptId
          ORDER BY ScriptLineId FOR XML PATH('')
       ) AS FromAnotherTable,
       r.UnitName AS Store,
       r.UnitNumber
FROM CallCenterScript s WITH (NOLOCK)
     INNER JOIN CallCenterDNIS d WITH (NOLOCK) ON d.ScriptId = s.ScriptId
     INNER JOIN CallCenter c WITH (NOLOCK) ON c.Id = s.CallCenterId
     INNER JOIN CallCenterDNISRestaurant ccd WITH (NOLOCK) ON ccd.CallCenterDNISId = d.CallCenterDNISId
     INNER JOIN dbo.Restaurant r WITH (NOLOCK) ON r.RestaurantID = ccd.CallCenterRestaurantId
WHERE c.Id = 5
      AND (1 = 1)
      AND (s.IsDeleted = 0 OR s.IsDeleted IS NULL)
ORDER BY DNIS ASC;
输出:

这是有效的:

DECLARE @Column1 VARCHAR(50) = 'Foo',
        @Column2 VARCHAR(50) = NULL;

SELECT CONCAT(@Column1,@Column2);
SELECT COALESCE(@Column2, '') + @Column1
SELECT ISNULL(@Column2, '') + @Column1

因此,我不确定我的原始查询中缺少了什么。

查看您得到的结果中的第3行。在连接列(选项1、2、3)中,您将获得两次第一个脚本列。不是你想象的第一个+第二个

原因是您给子查询“script”添加了别名,该子查询与查询中的另一列同名,这使得它不明确

更改子查询的别名,问题就会消失。坦率地说,我很惊讶你的提问没有引起错误

编辑:不能在同一查询级别的另一列定义中使用列别名。换句话说,你不能这样做:

SELECT 
  SomeColumn AS A
, (Subquery that returns a column) AS B
, A + B  --this is not allowed
FROM ...
您可以创建一个CTE,返回别名列,然后在从CTE中选择的主查询中连接它们,或者必须使用别名的原始来源,如下所示:

SELECT 
  SomeColumn AS A
, (Subquery that returns a column) AS B
, SomeColumn  + (Subquery that returns a column)  --this is fine
FROM ...

我采用了另一种方法,在创建单独的列时,我在
子查询
中使用了
ISNULL
,它返回我想要的结果

查询:

SELECT DISTINCT
       c.Name AS CallCenter,
       LTRIM(RTRIM(s.Name)) Name,
       d.DNIS,
       s.ScriptId,
      s.Script AS Original,
      (
          SELECT TOP 5 CCSL.Line+'; ' 
          FROM CallCenterScriptLine CCSL
          WHERE CCSL.ScriptId = s.ScriptId
          ORDER BY ScriptLineId FOR XML PATH('')
       ) AS FromAnotherTable,
         --CONCAT(s.Script, SELECT TOP 5 CCSL.Line+'; ' FROM dbo.CallCenterScriptLine ccsl WHERE ccsl.ScriptId = s.ScriptId ORDER BY ccsl.ScriptLineId xml path(''))
         --CONCAT(Original, FromAnotherTable) AS Option1,
         --COALESCE(Original, '') + FromAnotherTable AS Option2,
         --ISNULL(Original, '') + FromAnotherTable AS Option3,,
       r.UnitName AS Store,
       r.UnitNumber
FROM CallCenterScript s WITH (NOLOCK)
     INNER JOIN CallCenterDNIS d WITH (NOLOCK) ON d.ScriptId = s.ScriptId
     INNER JOIN CallCenter c WITH (NOLOCK) ON c.Id = s.CallCenterId
     INNER JOIN CallCenterDNISRestaurant ccd WITH (NOLOCK) ON ccd.CallCenterDNISId = d.CallCenterDNISId
     INNER JOIN dbo.Restaurant r WITH (NOLOCK) ON r.RestaurantID = ccd.CallCenterRestaurantId
WHERE c.Id = 5
      AND (1 = 1)
      AND (s.IsDeleted = 0 OR s.IsDeleted IS NULL)
ORDER BY DNIS ASC;
SELECT DISTINCT
       c.Name AS CallCenter,
       LTRIM(RTRIM(s.Name)) Name,
       d.DNIS,
       s.ScriptId,
      s.Script AS Original,
      (
          SELECT TOP 5 ISNULL(CCSL.Line, '')+'; ' + ISNULL(s.Script, '')
          FROM CallCenterScriptLine CCSL
          WHERE CCSL.ScriptId = s.ScriptId
          ORDER BY ScriptLineId FOR XML PATH('')
       ) AS FromAnotherTable,
       r.UnitName AS Store,
       r.UnitNumber
FROM CallCenterScript s WITH (NOLOCK)
     INNER JOIN CallCenterDNIS d WITH (NOLOCK) ON d.ScriptId = s.ScriptId
     INNER JOIN CallCenter c WITH (NOLOCK) ON c.Id = s.CallCenterId
     INNER JOIN CallCenterDNISRestaurant ccd WITH (NOLOCK) ON ccd.CallCenterDNISId = d.CallCenterDNISId
     INNER JOIN dbo.Restaurant r WITH (NOLOCK) ON r.RestaurantID = ccd.CallCenterRestaurantId
WHERE c.Id = 5
      AND (1 = 1)
      AND (s.IsDeleted = 0 OR s.IsDeleted IS NULL)
ORDER BY DNIS ASC;

下面是一个使用表变量的简化示例

它不使用字段的子查询,而是使用交叉应用

海螺和其他材料一起被用来把绳子粘在一起。

结果:


我不确定您想要实现什么,但我已经查看了代码,我有一个问题:我看到您正在使用XML子句计算列脚本,下面的SELECT中有两行是指列脚本。你在做吗?小心到处使用nolock提示。这比大多数人意识到的要险恶得多@基本上,我只从一张桌子上读,现在我从两张桌子上读。使用XML的唯一原因是将多行合并到一行中。这是否回答了您的问题?您为什么要连接
s.Script+';',脚本
?你认为
s.Script
Script
之间有什么区别?你的别名子查询?尝试给它一个不同的名字以避免歧义。有意义。如果我将
s.Script命名为原始
,将子查询命名为另一个表的
或任何其他名称,则我不能使用
CONCAT
。它使我的别名出现无效列名错误。