Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TSQL-Alternative resultset when IN子句返回空_Sql_Sql Server_Tsql - Fatal编程技术网

TSQL-Alternative resultset when IN子句返回空

TSQL-Alternative resultset when IN子句返回空,sql,sql-server,tsql,Sql,Sql Server,Tsql,我需要帮助在更大的CTE查询中实现过滤器 想象一下这个场景: 可能属于多个类别的项目列表 用户遵循其中一个类别 过滤器:用户可以指定,当跟随一个类别时,他/她只想查看至少属于他/她可以指定的一个辅助类别的项目 示例:用户遵循“计算机”类别,并指定仅希望查看“平板电脑”。当用户查看“计算机”时,查询应仅选择也属于“平板电脑”类别的项目。如果未指定过滤器,则应显示主类别(“计算机”)的所有项目 SQL Fiddle目前似乎存在一些问题,这说明了问题的存在 SELECT * FROM ItemsT

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

想象一下这个场景:

  • 可能属于多个类别的项目列表
  • 用户遵循其中一个类别
  • 过滤器:用户可以指定,当跟随一个类别时,他/她只想查看至少属于他/她可以指定的一个辅助类别的项目
示例:用户遵循“计算机”类别,并指定仅希望查看“平板电脑”。当用户查看“计算机”时,查询应仅选择也属于“平板电脑”类别的项目。如果未指定过滤器,则应显示主类别(“计算机”)的所有项目

SQL Fiddle目前似乎存在一些问题,这说明了问题的存在

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。这似乎使它起作用了。谢谢你的帮助!