假设我有两个表:
我需要从TABLE2中检索TABLE1中所有ID的值,作为单个字符串。为了实现这一点,我做了下一个查询:
DECLARE @id INT, @value VARCHAR(10);
SELECT @id=0, @value='';
SELECT
@value = @value + (SELECT TOP 1 value FROM TABLE2 WHERE id=@id) + '-',
@id = @id+1
FROM TABLE1
但是当我运行此查询时,子查询总是返回null(因此,最后返回@value=NULL
)。我的问题是:为什么子查询SELECT TOP 1 value FROM TABLE2 WHERE id=@id
总是返回NULL,即使在TABLE2中找到了ID?
答案 0 :(得分:4)
这是一种非常奇怪的尝试实现树行者的方法,在SELECT中增加@id并期望它应用于子查询。它不起作用,因为SQL Server在查询设置阶段将子查询表达式的@id值锁定为常量。
请参阅此示例,其中返回的@value明确指示@id锁定为1.对于您的问题,它被锁定为0,因此每个子查询将返回NULL,表面上是因为@id = 0没有匹配
create table table1 (
id int);
create table table2 (
id int, value varchar(10));
insert table1 values (1),(2),(3),(4);
insert table2 values
(1,1),
(2,2),
(3,3),
(4,4);
DECLARE @id INT, @value VARCHAR(10);
SELECT @id=1, @value='';
SELECT
@value = @value + (SELECT TOP 1 value FROM TABLE2 WHERE id=@id) + '-',
@id = @id+1
FROM TABLE1;
select @value, @id
-- result
1-1-1-1 5
如果你只想要2的值,那么你只需要将子查询与table.id相关联,而不是变量@id,如下所示:
create table table1 (id int);
create table table2 (id int, value varchar(10));
insert table1 values (1),(2),(3),(4);
insert table2 values
(1,1),
(3,9),
(4,4);
DECLARE @value VARCHAR(10);
SELECT @value='';
SELECT
@value = @value + isnull((SELECT TOP 1 value
FROM TABLE2
WHERE id=table1.id) + '-','')
FROM TABLE1;
select @value
-- Result
1-9-4
答案 1 :(得分:1)
另一个解决方案(如果table2中的值为NOT NULL,则此方法仅在table2的值之间附加' - '分隔符):
declare @id int, @value varchar(max);
select @id = 0, @value='';
select
@value = @value + isnull(value,'') + case when value is null then '' else '-' end
from
table2 t2
where
t2.id in (select id from table1)
答案 2 :(得分:1)
这是因为你在0开始你的@id除非你的表中的id为0,否则你可能需要这样做:SELECT @ id = 1
或者,您可以将其浓缩为此而不使用id:
SELECT @value = @value + value + '-'
FROM TABLE2 t2
INNER JOIN TABLE1 t1 ON t1.id = t2.id