我有一个带有多个连接的查询,我希望将两列中的记录合并为一个。如果一列是空的,那么我想显示一个列值作为结果。我尝试使用CONCAT
,COALEASE
和ISNULL
,但没有运气。我在这里缺少什么?
我的目标是,在查询中创建一个包含s.Script AS Original
和FromAnotherTable
组合的列。以下查询运行但会抛出Invalid column name 'Original'
和Invalid column name 'FromAnotherTable'
。当我尝试使用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;
这有效:
DECLARE @Column1 VARCHAR(50) = 'Foo',
@Column2 VARCHAR(50) = NULL;
SELECT CONCAT(@Column1,@Column2);
SELECT COALESCE(@Column2, '') + @Column1
SELECT ISNULL(@Column2, '') + @Column1
所以我不确定我在原始查询中缺少什么。
答案 0 :(得分:2)
查看您获得的结果中的第3行。在连接列(选项1,2,3)中,您将获得第一个脚本列两次。不是第一个+第二个像你期望的那样。
原因是因为您已将子查询别名"脚本"与查询中的另一列名称相同,这使其不明确。
更改子查询的别名,问题应该消失。我坦率地说你的查询没有引起错误。
编辑:您不能在同一级别的查询中使用另一列定义中的列别名。换句话说,你不能这样做:
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 ...
答案 1 :(得分:0)
我采用了另一种方法,而不是创建单独的列,我在ISNULL
中使用了subQuery
,它返回了我想要的结果。
<强>查询:强>
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;
答案 2 :(得分:0)
这是使用表变量的简化示例。
它不使用字段的子查询,而是使用CROSS APPLY。
CONCAT与STUFF结合用于将字符串粘合在一起。
declare @Foo table (fooID int identity(1,1) primary key, Script varchar(30));
declare @Bar table (barID int identity(1,1) primary key, fooID int, Line varchar(30));
insert into @Foo (Script) values
('Test1'),('Test2'),(NULL);
insert into @Bar (fooID, Line) values
(1,'X'),(1,'Y'),(2,NULL),(3,'X'),(3,'Y');
select
f.fooID,
f.Script,
x.Lines,
CONCAT(Script+'; ', STUFF(x.Lines,1,2,'')) as NewScript
from @Foo f
cross apply (
select '; '+b.Line
from @Bar b
where b.fooID = f.fooID
FOR XML PATH('')
) x(Lines)
结果:
fooID Script Lines NewScript
----- ------- ------- -----------
1 Test1 ; X; Y Test1; X; Y
2 Test2 NULL Test2;
3 NULL ; X; Y X; Y