dis*_*ive 1 sql t-sql sql-server
我希望返回一系列数值结果(即列的结果)并将这些逗号分开.因此,输出可以由IN另一个查询中的子句使用.因此,当表数据如下时,我正在寻找10,20,30,40,50,60作为输出:
ID Value
1 10
2 20
3 30
4 40
5 50
6 60
Run Code Online (Sandbox Code Playgroud)
最聪明的方法是什么?以下查询将以下列方式使用此输出字符串:
select * from Table where Value IN (10,20,30,40,50,60)
Run Code Online (Sandbox Code Playgroud)
我已经尝试创建一个获取select输出的变量,但我只得到一个值.即
declare @Value_List varchar(799);
select @Value_List = Value from Table select @Value_List;
Run Code Online (Sandbox Code Playgroud)
但是我只返回一个值,更不用说列表了.
理由是这是一个调试脚本,我们需要手动完成一系列检查,因此理想情况下要将查询分解为单个语句,以便于使用和清晰.
要做你想做的事,你需要使用动态SQL.但是你能更好地解释为什么你想这样做吗?看起来要简单得多:
SELECT *
FROM Table
WHERE Value IN (SELECT Value FROM YourTable WHERE ID <= 6)
Run Code Online (Sandbox Code Playgroud)
1) 假设您的值列表没有像Lamak概述的更简单的方法解决(即您根本不需要列表),这里有一种使用动态SQL的方法:
-- Declare & get the list of values from a query.
DECLARE @values varchar(2000);
SET @values = '';
SELECT @values = @values + CAST(Value AS varchar(5)) + ','
FROM tbl_A; -- hopefully some WHERE criteria here to make this interesting
-- Trim the trailing comma.
SET @values = SUBSTRING(@values, 1, Len(@values) - 1)
---- DEBUG: Confirm the list of values.
--SELECT @values As 'Values'
--/*
--Values
-------------------------------------------------------------------------------
--10,20,30,40,50,60
--
--(1 row(s) affected)
--*/
-- Dynamically use the list of values in an IN clause.
DECLARE @sql as nvarchar(max);
SET @sql = 'SELECT Value FROM tbl_A WHERE Value IN (' + @values + ')';
EXEC sp_executesql @sql;
/*
Value
-----------
10
20
30
40
50
60
(6 row(s) affected)
*/
Run Code Online (Sandbox Code Playgroud)
SQLBook.com更深入地解释了这种方法.
2) 但是,当您可以使用一个子查询来获取IN子句中的值列表时,子查询会更智能- 例如:
SELECT a.Value
FROM tbl_A a
WHERE
a.Value IN
(SELECT b.Value
FROM tbl_B b
/* hopefully some WHERE criteria here to make this interesting */);
Run Code Online (Sandbox Code Playgroud)
3) 作为逗号分隔列表的更直接的替代方法,请考虑表值参数.它们可以简单,易读,优雅(根据您对Lamak的问题评论) - 即聪明.
考虑一个存储过程,它接受ID的"列表"作为ID的TVP(即集合):
/*
--------------------------------------------------------------------------------------
IntTableType for int TVPs (i.e. "the TVP")
--------------------------------------------------------------------------------------
*/
CREATE TYPE [dbo].[IntTableType] AS TABLE
(
Value int
)
GO
/*
--------------------------------------------------------------------------------------
Gets a set of Foos by ID. (i.e. "the stored proc")
--------------------------------------------------------------------------------------
*/
CREATE PROCEDURE [dbo].[uspGetFoos]
@FooIdTable dbo.IntTableType readonly
AS
BEGIN
SET NOCOUNT ON;
SELECT f.ID, f.Column1, f.Column2 -- etcetera
FROM dbo.Foo f
WHERE f.ID IN (SELECT fi.Value FROM @FooIdTable);
---- or --
--
--SELECT f.ID, f.Column1, f.Column2 -- etcetera
--FROM dbo.Foo f
--JOIN @FooIdTable fi ON fi.Value = f.ID;
END
GO
Run Code Online (Sandbox Code Playgroud)
然后,您可以在一个查询中获取ID的"列表"(即设置),并在您描述的另一个查询中使用它:
DECLARE @fooIds dbo.IntTableType;
INSERT INTO @fooIds (Value)
SELECT IntColumn
FROM dbo.Whatever
WHERE 1 = 1; -- whatever
EXEC dbo.uspGetFoos @FooIdTable = @fooIds;
Run Code Online (Sandbox Code Playgroud)
当然,您也可以类似地使用表变量或临时表来表示ID(前者仅限于单个存储过程,函数或批处理); 但TVP为您提供了一种将表格(即设置)数据作为输入参数的一流方法.
| 归档时间: |
|
| 查看次数: |
3097 次 |
| 最近记录: |