将动态表组合到一个查询中

时间:2011-11-14 19:41:28

标签: sql sql-server sql-optimization

是否有一种干净的方法将下面的SQL组合成1个语句? FilterID可以是零长度,因此Filters表是可选的。因此,除非有更好的方法,否则我“被迫”使用下面的EXISTS逻辑。

我已经意识到了......
我已经意识到我可以构建一个动态字符串并使用EXEC来运行它......但这很慢。

文档到文档元数据的关系是: 1 Document到许多DocumentMetadata的左右 过滤到文档元数据的关系是: 1 Filter到许多DocumentMetadata

SQL如下:

   DECLARE @SearchTerms NVARCHAR(MAX)
    DECLARE @FilterIDs  VARCHAR(100)
    SET @SearchTerms        = '7%'
    SET @FilterIDs      = '12'
    ------------------------
    DECLARE @Filters TABLE (FilterID int)

    IF(@FilterIDs IS NOT NULL)
            INSERT INTO @Filters SELECT items AS INT FROM Split(@filterIDs, ',')

    IF EXISTS(SELECT FilterID FROM @Filters)
        BEGIN
            SELECT
                Document.ID AS DocumentID
                ,Document.SourceID
                ,Document.Name
                ,Document.Title
                ,Document.DocumentUrl
                ,Document.DocType
                ,Document.DocumentModifiedDate
                ,Document.Library
                ,DocumentMetadata.ID AS DocumentMetadataID
                ,DocumentMetadata.DocumentID
                ,DocumentMetadata.FilterID
                ,DocumentMetadata.Value
            FROM Document
            JOIN DocumentMetadata
                ON DocumentMetadata.DocumentID = Document.ID
            JOIN Filter
                ON Filter.ID = DocumentMetadata.FilterID
                AND Filter.ID IN (SELECT FilterID FROM @Filters)
            WHERE
                Document.Name LIKE @SearchTerms
                OR Document.Title LIKE @SearchTerms
            ORDER BY
                Document.Name, Document.Title
        END
    ELSE
        BEGIN
            SELECT
                Document.ID AS DocumentID
                ,Document.SourceID
                ,Document.Name
                ,Document.Title
                ,Document.DocumentUrl
                ,Document.DocType
                ,Document.DocumentModifiedDate
                ,Document.Library
                ,DocumentMetadata.ID AS DocumentMetadataID
                ,DocumentMetadata.DocumentID
                ,DocumentMetadata.FilterID
                ,DocumentMetadata.Value
            FROM Document
            JOIN DocumentMetadata
                ON DocumentMetadata.DocumentID = Document.ID
            JOIN Filter
                ON Filter.ID = DocumentMetadata.FilterID
            WHERE
                Document.Name LIKE @SearchTerms
                OR Document.Title LIKE @SearchTerms
            ORDER BY
                Document.Name, Document.Title
        END

1 个答案:

答案 0 :(得分:0)

JOIN Filter ON Filter.ID = DocumentMetadata.FilterID 
AND (Filter.ID IN (SELECT FilterID FROM @Filters) OR @FilterIDs is null) 

这应该涵盖你是否在@filters表中有项目,或者你有进入filtersID(它驱动Filters表)的null。在OR子句中出现null的情况下,允许记录通过,因此它依赖于join语句的另一部分,这在您的语句之间是通用的。这应该让你只使用1个select子句来覆盖它们。