将动态表组合成一个查询

发布于 2024-12-15 05:33:47 字数 2739 浏览 2 评论 0原文

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

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

文档到文档元数据的关系是: 1 个文档 到多个DocumentMetadata
Filter-to-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

Is there a clean way to combine the SQL below into 1 statement? The FilterID's can be zero-length, so the Filters table is optional. So, unless there is a better way to do it, I am "forced" to use the EXISTS logic below.

I Already Realize...
I already realize I can build a dynamic String and use the EXEC to run it...but that is slow.

The Document-to-DocumentMetadata relationship is: 1 Document to many DocumentMetadata's
The Filter-to-DocumentMetadata relationship is: 1 Filter to many DocumentMetadata's

The SQL Is As Follows:

   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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执笔绘流年 2024-12-22 05:33:47
JOIN Filter ON Filter.ID = DocumentMetadata.FilterID 
AND (Filter.ID IN (SELECT FilterID FROM @Filters) OR @FilterIDs is null) 

这应该涵盖@filters 表中是否有项目,或者filtersID(驱动Filters 表)是否有空值。在 OR 子句中出现 null 的情况下,让记录通过,因此它依赖于语句之间常见的 join 子句的其他部分。这应该让您只需使用 1 个 select 子句即可涵盖两者。

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

That should cover whether you have items in the @filters table or you had null come in for the filtersID (which drives the Filters table). In the case null came in the OR clause lets the record thru, so it relies on the other part of the join clause which is common between your statements. That should let you just use 1 select clause to cover both.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文