子查询返回的值超过1。内部查询

时间:2013-04-23 16:29:57

标签: sql sql-server sql-server-2008

我有两张表tbl_Categorytbl_Course

tbl_Category我有这样的行:

 CatID CatName CatDesc
  1     Cat1   catDesc1
  2     Cat2   catDesc2
  3     Cat3   catDesc3
  4     Cat4   catDesc4
  5     Cat5   catDesc5

tbl_course中的值类似

CoursID Name AssignCategory AdditionalCat
 1       cou1   1             2,3
 2       cou2   2               3
 3       cou3   1             3,4 

我需要结果如下

包含AsignCategory和additionalcat

的类别
 CatID CatName CatDesc
  1     Cat1   catDesc1
  2     Cat2   catDesc2
  3     Cat3   catDesc3
  4     Cat4   catDesc4

不包含AsignCategory和additionalcat的类别

 CatID CatName CatDesc
  5     Cat5   catDesc5

我正在使用此分割功能

CREATE FUNCTION dbo.StrSplit (@sep char(1), @s varchar(512))  
RETURNS table  
AS  
RETURN (  
    WITH Pieces(pn, start, stop) AS (  
      SELECT 1, 1, CHARINDEX(@sep, @s)  
      UNION ALL  
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)  
      FROM Pieces  
      WHERE stop > 0  
    )  
    SELECT pn,  
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s  
    FROM Pieces  
  )  

我使用下面的查询表单分配类别结果:

 select * from dbo.Tbl_Category
 where catid in(select assigncategory from Tbl_Course ) 

 )

 select * from dbo.Tbl_Category
 where catid not in(select assigncategory from Tbl_Course          
 )

请使用上述查询帮我处理其他类别的结果。

1 个答案:

答案 0 :(得分:3)

您应该使用CROSS APPLY来使用StrSplit udf:

SELECT * FROM dbo.tbl_Category
WHERE CatID IN(
    SELECT AssignCategory 
    FROM tbl_Course
    UNION
    SELECT CAST(split.S as int) 
    FROM tbl_Course
    CROSS APPLY dbo.StrSplit(',', AdditionalCat) as split )

SELECT * FROM dbo.tbl_Category
WHERE CatID NOT IN(
    SELECT AssignCategory 
    FROM tbl_Course
    UNION
    SELECT CAST(split.S as int) 
    FROM tbl_Course
    CROSS APPLY dbo.StrSplit(',', AdditionalCat) as split )

SQLFiddle here

您也可以使用UNPIVOT来避免使用UNION。但由于只有2列需要合并,因此UNION可能“足够好”用于此目的。