在选择查询中使用的逗号分隔字段中的行数据

时间:2015-03-31 02:52:45

标签: sql-server database

我正在尝试构建一个返回的单个选择查询 使用Table1的产品类型描述列表不是 在ExcludedList的{​​{1}}。

我在SQL Server 2008中有以下表格和数据。

Table2

查询应返回以下内容:

Table1(nProdType INT, sProdDesc VARCHAR)

nProdType   SProdDesc
----------- --------------------
1           Pencils
2           Paper
3           Pens
4           Markers
5           Erasers
6           Crayons
7           HighLighters
8           Rulers


Table2(ClassID INT, ExcludeList VARCHAR)

ClassID     ExcludedList
----------- --------------------
100         2,3,4,8
101         1,2,5,6,7,8
102         4,5,6,7
103         1,2,3,4,5,6,7,8
104         7

..等等..

我知道如何构建(当然在SO中有很多解决方案)一个分隔逗号分隔字段的函数但是它们返回 ALL 表中的行,我希望它是每条记录(ClassID nProdType sProdDesc -------- --------- -------------- 100 1 Pencils 100 5 Erasers 100 6 Crayons 100 7 HighLighters 101 3 Pens 101 4 Markers 102 1 Pencils 102 2 Paper 102 3 Pens 102 8 Rulers ),以便我可以查询ClassID中的内容。我试图不在C#中编写代码或使用RecordSet。

1 个答案:

答案 0 :(得分:0)

您可以使用CSV分配器。以下是Jeff Moden的 DelimitedSplit8K 函数。

;WITH CteDelimitted AS(
    SELECT
        t.ClassID,
        nProdType = CAST(s.Item AS INT)
    FROM Table2 t
    CROSS APPLY dbo.DelimitedSplit8K(t.ExcludedList, ',') s
),
CteCross AS(
    SELECT
        t2.ClassID,
        t1.nProdType,
        t1.SprodDesc
    FROM Table1 t1
    CROSS JOIN(
        SELECT DISTINCT ClassID FROM Table2
    )t2

)
SELECT * 
FROM CteCross c
WHERE NOT EXISTS(
    SELECT 1
    FROM CteDelimitted
    WHERE
        ClassID = c.ClassID
        AND nProdType = c.nProdType
)
ORDER BY ClassID, nProdType

SQL Fiddle


使用NOT IN的另一种方法:

WITH Cte AS(
    SELECT
        t2.ClassID,
        t1.nProdType,
        t1.SprodDesc
    FROM Table1 t1
    CROSS JOIN(
        SELECT DISTINCT ClassID FROM Table2
    )t2
)
SELECT *
FROM Cte c
WHERE c.nProdType NOT IN(
    SELECT CAST(s.Item AS INT)
    FROM Table2
    CROSS APPLY dbo.DelimitedSplit8K(ExcludedList, ',') s
    WHERE ClassID = c.ClassID
)
ORDER BY ClassID, nProdType

SQL Fiddle