假设我有两个表:
- 表1:具有标识我需要处理的清单。
- TABLE2:有ID和值的键值对。
我需要检索来自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,即使ID是表2中发现了什么?
这是试图实现treewalker,在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想要的值,然后的替代变量@id,你只要相关子查询,如下table.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
这是因为你是从0开始的@id除非你在你的表有0的ID,你可能需要做:SELECT @ ID = 1
或者,你可以把它浓缩到这一点,并没有使用id:
SELECT @value = @value + value + '-'
FROM TABLE2 t2
INNER JOIN TABLE1 t1 ON t1.id = t2.id
又一解决方案(这只是一个追加“ - ”表2从值之间的分隔符如果从表2的值是NOT NULL):
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)