如何将两个查询组合为SQL中的单个结果集 - 类别 - 子类别?

时间:2010-02-26 14:33:34

标签: 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() 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上其他人的帮助,会列出所有具有Given SubCategory的项目 - 但是我希望能够包含以下内容:

    SELECT DISTINCT RTRIM(LTRIM(CategoryCode)) + '%' AS Pattern
    FROM tblCategories
    WHERE CategoryID = @CategoryID) Cats
    JOIN tblStock Stock
    ON Stock.CategoryCode LIKE Cats.Pattern

因此,它将类别作为集合,然后SubCategories是这个的SubSet,例如我有一个EG类别,其中包含两个子类别EG-EG和EG-IE,它们本身就是类别代码列表,例如:

EG-EG
- ETC
- ECT
- TCE
EG-IE
- EIEG
- EGIE

我如何得到它所以它然后从这个List然后做了子类别,因为我需要一个“非”行为,因为将有一个通用类别,它将获取SubCategories上的所有左侧,没有具体说明,但会被类别查询选中。

我找不到合适的组合 - 子类别和类别单独工作,但我希望它们是彼此的超集和子集。


这是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
)

我有一个有效的解决方案,但是性能是不可接受的,任何人都可以帮忙解决这个问题,因为我已经研究了一段时间并且似乎找不到优化方法 - SubCategories是一个子集分类如果有帮助,请参阅下面的示例:

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)

3 个答案:

答案 0 :(得分:3)

嗯,如果没有表定义,键,索引查询计划或数据示例,它是不可能的,但我认为这会有所帮助:

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
)

答案 1 :(得分:0)

从根本上说,如果我正确地遵循要求(并且没有表格模式和所包含数据的知识,那就太复杂了),你将别名为“Info”的内部子查询需要包含两个UNION ALLed查询 - - tblCategories上的“新”和tblSubCategories上的“旧”。

棘手的部分将是订购,特别是因为您当前的排序标准(AddedDate)似乎与您所需的排序标准(Category和SubCategory)无关。尽力而为,并在此基础上添加一些仅用于订购的列。

答案 2 :(得分:0)

尝试使用核心SELECT:

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))+'%'
    )

摆脱了两个DISTINCT。

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

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