T-SQL逗号分隔从子结构中的结果集到子句的值

时间:2013-07-08 17:30:30

标签: sql sql-server-2008 tsql

我有一个问题,在我的数据中,我将返回一个列值看起来像

的记录

- 查询

Select col1 from myTable where id = 23

- col1的结果 111,104,34,45

我想将这些值提供给in子句。到目前为止,我已经尝试过:

- 查询2 - 尝试1

Select * from mytableTwo
where myfield in (
SELECT col1
from myTable where id = 23)

- 查询2 - 尝试2

Select * from mytableTwo
where myfield in (
SELECT '''' +  
Replace(col1, ',', ''',''') + ''''
from myTable where id = 23)

- 查询2测试 - 这可以并且将返回数据,因此我在此验证数据是否存在

Select * from mytableTwo
where myfield in ('111', '104', '34', '45')

为什么查询2没有尝试1或2工作?

3 个答案:

答案 0 :(得分:1)

您不需要in子句。您想使用like

select *
from myTableTwo t2
where exists (select 1
              from myTable t
              where id = 23 and
                    ', '+t.col1+', ' like '%, '+t2.myfield+', %' 
             );

这使用like进行列表中的比较。它使用子查询作为值。您也可以通过执行以下操作将其标记为join

select t2.*
from myTableTwo t2 join
     myTable t
     on t.id = 23 and
        ', '+t.col1+', ' like '%, '+t2.myfield+', %';

但是,如果id = 23中有多个myTable行,则可能会增加输出中的行数。

答案 1 :(得分:0)

如果仔细观察,请查询2 - 尝试1&查询2 - 尝试2被视为单个值。

像这样:

WHERE myfield in ('111, 104, 34, 45')

与以下内容不同:

WHERE myfield in ('111', '104', '34', '45')

因此,如果您打算从MyTableTwo过滤myTable行,则需要将字段列数据的值提取到表变量/表值函数并过滤数据。

我创建了一个表值函数,它接受逗号分隔的字符串并返回一个表值。 你可以在这里参考T-SQL : Comma separated values to table

过滤数据的最终代码:

DECLARE @filteredIds VARCHAR(100)

-- Get the filter data
SELECT @filteredIds = col1
FROM myTable WHERE id = 23

-- TODO : Get the script for [dbo].[GetDelimitedStringToTable] 
-- from the given link and execute before this
SELECT * 
FROM mytableTwo T
CROSS APPLY [dbo].[GetDelimitedStringToTable] ( @filteredIds, ',') F
WHERE T.myfield = F.Value

请告诉我这是否对您有所帮助!

答案 2 :(得分:0)

我认为col是一种字符类型,其结果类似于'111, 104, 34, 45'。如果这是您的情况,那么它不是世界上最好的(非规范化数据库),但您仍然可以使用LIKECHARINDEX等字符运算符来关联这些表。唯一的问题是将数字列转换为字符 - 字符和数字之间的默认转换是数字,它将导致转换错误。

自从@Gordon使用LIKE回复后,我使用CHARINDEX提供了一个解决方案:

SELECT *
FROM mytableTwo tb2
WHERE EXISTS (
    SELECT 'x'
    FROM myTable tb1
    WHERE tb1.id = 23
    AND CHARINDEX(CONVERT(VARCHAR(20), tb2.myfield), tb1.col1) > 0
)