我正在尝试构建一个返回的单个选择查询
使用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。
答案 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
使用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