TSQL-Alternative resultset when IN子句返回空
我需要帮助在更大的CTE查询中实现过滤器 想象一下这个场景:TSQL-Alternative resultset when IN子句返回空,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要帮助在更大的CTE查询中实现过滤器 想象一下这个场景: 可能属于多个类别的项目列表 用户遵循其中一个类别 过滤器:用户可以指定,当跟随一个类别时,他/她只想查看至少属于他/她可以指定的一个辅助类别的项目 示例:用户遵循“计算机”类别,并指定仅希望查看“平板电脑”。当用户查看“计算机”时,查询应仅选择也属于“平板电脑”类别的项目。如果未指定过滤器,则应显示主类别(“计算机”)的所有项目 SQL Fiddle目前似乎存在一些问题,这说明了问题的存在 SELECT * FROM ItemsT
- 可能属于多个类别的项目列表
- 用户遵循其中一个类别
- 过滤器:用户可以指定,当跟随一个类别时,他/她只想查看至少属于他/她可以指定的一个辅助类别的项目
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子句返回空时,如何返回所有记录?嗯,最明显的是这样的:
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
如果这执行得不好,您可以尝试一些变体,例如使用
(选择top 1 ItemPk…)为null
或类似的内容。CTE将允许您避免两次写入同一个SQL(如果不是生成SQL,则很有用)。格式非常好的问题和示例+1当crbc_CTE.FkCategoryView不为空时,为什么要左键加入crbc_CTE?这是一个规则的内部连接。也不需要在子选择中使用DISTINCT,没有区别。你是对的,这是几次不同尝试的结果。。。在发布之前就这样结束了。这就是我需要帮助返回不同案例所需数据的地方。谢谢你的回复。但是,在最后一种情况下,当您指定了要筛选的辅助类别,并且没有具有该类别的项目时,此解决方案将失败。它正在选择所有项目,并且应该不选择任何项目。@ca2s7l好吧,在这种情况下,您为什么不检查一下类别是否被选中?如果我们上次更改的联接中的值等于所需类别中的“不同”,则它似乎起作用。像这样:。。。和crbc_cte.fkCategoryRequestsWH3_cte.FkCategory。这似乎使它起作用了。谢谢你的帮助!