TSQL - IN子句返回空

时间:2015-10-15 14:20:50

标签: sql sql-server tsql

我需要帮助在更大的CTE查询中实现过滤器。

想象一下这种情况:

  • 可能属于多个类别的项目列表。
  • 用户遵循其中一个类别。
  • 过滤器:用户可以指定当遵循一个类别时,他/她只想查看同样属于他/她可以指定的至少一个辅助类别的项目。

示例:用户遵循类别'计算机'并指明只想查看平板电脑'。当用户查看“计算机”时,查询应仅选择也属于“平板电脑”的项目。类别。如果没有指定过滤器,则应显示主类别(' Computers')的所有项目。

SQL Fiddle目前似乎有一些问题,so here's a little schema and query (at the end)说明问题

SELECT * FROM ItemsToShowWithCategories itswh_cte1
WHERE /* Other filters AND */
    itswh_cte1.ItemPk IN (
        SELECT DISTINCT itswh_cte2.ItemPk
        FROM ItemsToShowWithCategories AS itswh_cte2
        INNER JOIN ItemsToShowWithCategories AS itswh3_cte
            ON itswh_cte2.ItemPk=itswh3_cte.ItemPk
        LEFT JOIN CategoriesRequiredByCategory_CTE AS crbc_cte
            ON itswh_cte2.FkCategory=crbc_cte.FkCategoryView
           AND crbc_cte.FkCategoryRequired=itswh3_cte.FkCategory
        WHERE crbc_cte.FkCategoryView IS NOT NULL
    );

问题:当IN子句返回空时,如何返回所有记录?

1 个答案:

答案 0 :(得分:1)

嗯,最明显的是这样的事情:

WHERE /* Other filters AND */
    itswh_cte1.ItemPk IN (
        SELECT itswh_cte2.ItemPk
        FROM ItemsToShowWithCategories AS itswh_cte2
        INNER JOIN ItemsToShowWithCategories AS itswh3_cte
            ON itswh_cte2.ItemPk=itswh3_cte.ItemPk
        LEFT JOIN CategoriesRequiredByCategory_CTE AS crbc_cte
            ON itswh_cte2.FkCategory=crbc_cte.FkCategoryView
           AND crbc_cte.FkCategoryRequired=itswh3_cte.FkCategory
        WHERE crbc_cte.FkCategoryView IS NOT NULL
    )
    or 
    (SELECT count(ItemPk)
        FROM ItemsToShowWithCategories AS itswh_cte2
        INNER JOIN ItemsToShowWithCategories AS itswh3_cte
            ON itswh_cte2.ItemPk=itswh3_cte.ItemPk
        LEFT JOIN CategoriesRequiredByCategory_CTE AS crbc_cte
            ON itswh_cte2.FkCategory=crbc_cte.FkCategoryView
           AND crbc_cte.FkCategoryRequired=itswh3_cte.FkCategory
        WHERE crbc_cte.FkCategoryView IS NOT NULL) = 0

如果效果不佳,可以尝试一些变体,例如使用(select top 1 ItemPk ...) is null或类似的东西。 CTE将允许您避免两次写入相同的SQL(如果这不是生成SQL,则非常有用)。