如何在SQL中将两个查询组合为一个结果集,用于类别-子类别?

如何在SQL中将两个查询组合为一个结果集,用于类别-子类别?,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,我有以下功能: CREATE FUNCTION [dbo].[ListStockBySubCategory] ( @CategoryID varchar(10), @SubCategoryID varchar(10), @startRowIndex int, @maximumRows int ) RETURNS TABLE AS RETURN ( SELECT ISBN FROM ( SELECT ISBN, ROW_NUMBER() OVE

我有以下功能:

CREATE FUNCTION [dbo].[ListStockBySubCategory]
(   
    @CategoryID varchar(10),
    @SubCategoryID  varchar(10),
    @startRowIndex  int,
    @maximumRows    int
)
RETURNS TABLE 
AS
RETURN 
(
SELECT ISBN FROM (
SELECT ISBN, 
ROW_NUMBER() OVER(AddedDate DESC) AS RowNum
FROM (
        SELECT DISTINCT RTRIM(LTRIM(CategoryCode)) + '%' AS Pattern
        FROM tblSubCategories
        WHERE SubCategoryID = @SubCategoryID) Cats
        JOIN tblStock Stock
        ON Stock.CategoryCode LIKE Cats.Pattern 
) AS Info
WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1
)
感谢StackOverflow上其他人的帮助,它将列出具有给定子类别的所有项目-但是我希望能够包括以下内容:

    SELECT DISTINCT RTRIM(LTRIM(CategoryCode)) + '%' AS Pattern
    FROM tblCategories
    WHERE CategoryID = @CategoryID) Cats
    JOIN tblStock Stock
    ON Stock.CategoryCode LIKE Cats.Pattern
因此,它将类别作为一个集合,然后子类别是其中的一个子集,例如,我有一个EG类别,它包含两个子类别EG-EG和EG-IE,它们本身是一个类别代码列表,例如:

乙二醇 -等 -ECT -TCE EG-IE -EIEG -埃吉

如何得到它,它会从这个列表中得到类别,然后再得到子类别,作为这项工作的一部分,我需要一个NOT行为,因为将有一个通用类别,它将拾取所有未明确说明的剩余子类别,但将由类别查询拾取

我就是找不到合适的组合——子类别和类别是分开工作的,但我希望它们是彼此的超集和子集

以下是ListStockByCategoryFunction的功能:

CREATE FUNCTION [dbo].[ListStockByCategory]
(   
    @CategoryID varchar(10),
    @startRowIndex  int,
    @maximumRows    int
)
RETURNS TABLE AS
RETURN
(
SELECT ISBN FROM (SELECT ISBN, 
ROW_NUMBER() OVER(ORDER BY AddedDate DESC) AS RowNum
FROM (
        SELECT DISTINCT RTRIM(LTRIM(CategoryCode)) + '%' AS Pattern
        FROM tblCategory
        WHERE CategoryID = @CategoryID) Cats
        JOIN tblStock Stock
        ON Stock.CategoryCode LIKE Cats.Pattern
) AS Info
WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1
)
我有一个可行的解决方案,但是性能不可接受,有人能帮我吗,因为我已经做了一段时间,似乎找不到优化的方法-子类别是类别的子集如果这有帮助,请参见下面的示例:

CREATE FUNCTION [dbo].[ListStockBySubCategory]
(   
    @CategoryID     varchar(10),
    @SubCategoryID  varchar(10),
    @startRowIndex  int,
    @maximumRows    int
)
RETURNS TABLE 
AS
RETURN (
SELECT ISBN FROM (
SELECT ISBN,
ROW_NUMBER() OVER(ORDER BY AddedDate DESC) AS RowNum
FROM BooksInStock WHERE ISBN IN
(SELECT ISBN FROM(SELECT DISTINCT RTRIM(LTRIM(CategoryCode)) + '%' AS Pattern
        FROM tblCategories
        WHERE CategoryID = @CategoryID) Cats
        JOIN tblStock Stock
        ON Stock.CategoryCode LIKE Cats.Pattern
WHERE 
ISBN IN
(SELECT ISBN FROM(SELECT DISTINCT RTRIM(LTRIM(CategoryCode)) + '%' AS Pattern
        FROM tblSubCategories
        WHERE SubCategoryID = @SubCategoryID) Cats
        JOIN tblStock Stock
        ON Stock.CategoryCode LIKE Cats.Pattern))
) AS Info WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1)

通常,如果我正确地遵循了需求,并且没有表模式和所包含数据的知识,那么它是非常复杂的,您别名为Info的内部子查询将需要包含两个联合调用的查询,一个是关于tblCategories的新查询,另一个是关于tblSubCategories的旧查询


棘手的部分将是确定排序,特别是因为您当前的排序标准addedate似乎与所需的排序标准类别和子类别无关。解决这个问题,并在此基础上添加一些仅用于订购的列。

尝试以下核心选择:

SELECT ISBN FROM tblStock a
WHERE EXISTS (
    SELECT * FROM tblCategories b
    WHERE b.CategoryID = @CategoryID
      AND a.CategoryCode LIKE RTRIM(LTRIM(b.CategoryCode))+'%'
    )
  AND EXISTS (
    SELECT * FROM tblSubCategories b
    WHERE b.SubCategoryID = @SubCategoryID
      AND a.CategoryCode LIKE RTRIM(LTRIM(b.CategoryCode))+'%'
    )
这样就消除了两个区别

除此之外,您还有一个看起来很昂贵的查询,它可能会从更好的索引中受益


如果您为tblStock、tblCategories、tblSubCategories和BooksInStock提供了DDL语句,包括所有索引和键约束,我可以在那里提供一些建议。

好的,如果没有表定义、键、索引查询计划或数据示例,这是不可能的,但我认为这将有助于:

CREATE FUNCTION [dbo].[ListStockBySubCategory]
(   
    @CategoryID     varchar(10),
    @SubCategoryID  varchar(10),
    @startRowIndex  int,
    @maximumRows    int
)
RETURNS TABLE AS
RETURN 
(
    SELECT ISBN FROM 
    (
        SELECT  ISBN,  ROW_NUMBER() OVER(ORDER BY AddedDate DESC) AS RowNum
        FROM BooksInStock 
        WHERE EXISTS
        (        
            SELECT *

            FROM tblStock AS stk
            JOIN tblStock AS stk2         ON stk.ISBN = stk2.ISBN
            JOIN tblCategories AS cat     ON cat.CategoryID = @CategoryId
            JOIN tblSubCategories AS sub  ON cat.CategoryID = sub.CategoryID

            WHERE cat.CategoryID = @CategoryId
              AND sub.CategoryID = @CategoryId
              AND bis.ISBN = stk.ISBN
              AND  stk.CategoryCode LIKE RTRIM(LTRIM(cat.CategoryCode))+'%'
              AND stk2.CategoryCode LIKE RTRIM(LTRIM(sub.CategoryCode))+'%'
        )
    ) AS Info 
    WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1
)

第一个结果集如何映射/连接/关联到第二个结果集?如果没有明确的答案,我怀疑是否有人能正确回答我不确定我在这里是否非常清楚-如果这有帮助的话,我将完整地添加其他函数。我已经添加了到目前为止的解决方案和悬赏,因此可以找到更有效的方法-我尝试了INTERSECT和Exception,但这会将读数增加10倍。我需要一个最少阅读量的解决方案来解决这个问题。感谢到目前为止的回复-我要等几天才能尝试它们,但到时候会给出答案!我没有看到您的CREATETABLE&CREATEINDEX语句,也没有看到示例数据。如果你想要好的性能,你需要给我们一些我们可以测试性能的东西。我想你可能是对的,tblCategories和tblSubCategories的并集是我想要的-我只是无法让它工作,没有SQL错误。你在编写并集、将行数应用到子查询时有问题吗,或者过滤/排序结果?我建议按照这个顺序处理这些问题-构建内部查询,然后进行检查。这仍然是一个问题,因为我不知道如何使这两个列表的子类别和类别一起工作。是的,我猜更多的信息会有所帮助,无论如何感谢这个示例,所有这些解决方案都为我提供了尝试的替代方案,这非常有帮助。这个解决方案以一种我没有考虑过的方式使用连接,尽管我有一个替代方案,我将此作为答案,因为这将是我想要实现的方式。