SQL Server - Как сделать выбор INTERSECT необязательным? - PullRequest
0 голосов
/ 03 апреля 2012

Я работаю над расширенным поиском и хотел бы знать, возможно ли включить часть моего выбора или нет на основе параметра. Я мог бы использовать IF ELSE для своего параметра, но у меня уже есть один для другого параметра, и это похоже на большое дублирование кода.

- Моя функция расширенного поиска позволяет пользователю задавать различные параметры. Базовый поиск может быть ТОЧНЫМ или нет (содержит против свободного текста - сначала, если), и могут быть указаны другие параметры (И). Определенные ключевые слова также могут быть выбраны (пересекаются).

Моя проблема в том, что когда @Keywords имеет значение null, я не хочу включать заключительную часть INTERSECT SELECT ... кода в конец моего примера. Есть ли быстрый способ сделать это без добавления еще одного IF ELSE в верхний и нижний запросы? Дайте мне знать, если вам нужна более подробная информация.

declare @SearchTerms nvarchar(4000)
declare @GalleryId int
declare @Keywords nvarchar(4000)
declare @ExactWord int
declare @BeginDateUpload datetime
declare @EndDateUpload datetime 
declare @BeginDateTaken datetime
declare @EndDateTaken datetime 
declare @MinFileSize int
declare @MaxFileSize int 
declare @AlbumType bit 
declare @ImageType int 
declare @AudioType int 
declare @OtherType int 
declare @VideoType int 

set @SearchTerms = 'tulips'
set @GalleryId = 1
set @Keywords = null -- 'st-jean'
set @ExactWord = null
set @BeginDateUpload  = null
set @EndDateUpload  = null 
set @BeginDateTaken  = null
set @EndDateTaken  = null 
set @MinFileSize  = null
set @MaxFileSize  = null 
set @AlbumType  = 1 
set @ImageType  = 1 
set @AudioType  = 1 
set @OtherType  = 1 
set @VideoType  = 1
IF ISNULL(@ExactWord, 0) = 1
    BEGIN
            [... snip ...]
    END
ELSE
  select t1.* from (    
    SELECT   'm' as objType, m.MediaObjectId  
    FROM gs_mediaObjectMetadata md 
         INNER JOIN dbo.[gs_MediaObject] m
         ON md.FKMediaObjectId = m.MediaObjectId
        INNER JOIN  dbo.[gs_Album] a
         ON a.AlbumId = m.FKAlbumId 
         WHERE FREETEXT (value, @SearchTerms) 
        AND  a.FKGalleryId = @GalleryId
        AND (m.DateAdded >= ISNULL(@BeginDateUpload, m.DateAdded))
        AND (m.DateAdded <= ISNULL(@EndDateUpload, m.DateAdded))
        AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(@BeginDateTaken, m.DateTaken))
        AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(@EndDateTaken, m.DateTaken))
        AND (m.OriginalSizeKB >= ISNULL(@MinFileSize, m.OriginalSizeKB))
        AND (m.OriginalSizeKB <= ISNULL(@MaxFileSize, m.OriginalSizeKB))
        AND((m.FKMediaObjectTypeId = ISNULL(@ImageType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@AudioType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@VideoType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@OtherType, 0)))



union

        SELECT 'm' as objType, m.MediaObjectId  
 FROM dbo.[gs_MediaObject] m
        INNER JOIN  dbo.[gs_Album] a
         ON a.AlbumId = m.FKAlbumId 
         WHERE FREETEXT ((m.Title, OriginalFilename), @SearchTerms) 
        AND  a.FKGalleryId = @GalleryId
        AND (m.DateAdded >= ISNULL(@BeginDateUpload, m.DateAdded))
        AND (m.DateAdded <= ISNULL(@EndDateUpload, m.DateAdded))
        AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(@BeginDateTaken, m.DateTaken))
        AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(@EndDateTaken, m.DateTaken))
        AND (m.OriginalSizeKB >= ISNULL(@MinFileSize, m.OriginalSizeKB))
        AND (m.OriginalSizeKB <= ISNULL(@MaxFileSize, m.OriginalSizeKB))
        AND((m.FKMediaObjectTypeId = ISNULL(@ImageType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@AudioType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@VideoType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@OtherType, 0)))
    )   t1
--IF @Keywords != null -- conditional intersect
 intersect

        SELECT 'm' as objType, m.MediaObjectId  
 FROM dbo.[gs_MediaObject] m
        INNER JOIN  dbo.[gs_Album] a
         ON a.AlbumId = m.FKAlbumId 
        left join dbo.gs_MediaObjectMetadata md
        on m.MediaObjectId = md.FKMediaObjectId
         WHERE FREETEXT ((m.Title, OriginalFilename), @SearchTerms) 
        AND  a.FKGalleryId = @GalleryId
        AND (m.DateAdded >= ISNULL(@BeginDateUpload, m.DateAdded))
        AND (m.DateAdded <= ISNULL(@EndDateUpload, m.DateAdded))
        AND (m.DateTaken is NULL OR m.DateTaken >= ISNULL(@BeginDateTaken, m.DateTaken))
        AND (m.DateTaken is NULL OR m.DateTaken <= ISNULL(@EndDateTaken, m.DateTaken))
        AND (m.OriginalSizeKB >= ISNULL(@MinFileSize, m.OriginalSizeKB))
        AND (m.OriginalSizeKB <= ISNULL(@MaxFileSize, m.OriginalSizeKB))
        AND((m.FKMediaObjectTypeId = ISNULL(@ImageType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@AudioType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@VideoType, 0))
        OR (m.FKMediaObjectTypeId = ISNULL(@OtherType, 0)))

and UPPER(md.Description) = 'KEYWORDS'
        and exists (
                SELECT *
                FROM    dbo.fnSplit(Replace(md.Value, '''', ''''''), ',') split
                WHERE   split.item in 
                (SELECT * from dbo.fnSplit(Replace(@Keywords, '''', ''''''), ','))
        )

Спасибо

1 Ответ

0 голосов
/ 03 апреля 2012

А что вместо того, чтобы делать пересечение, попробуйте это во внутренних запросах: @Keyword имеет значение null или .....

        and ( @Keywords is null or  (UPPER(md.Description) = 'KEYWORDS'
        and exists (
                SELECT *
                FROM    dbo.fnSplit(Replace(md.Value, '''', ''''''), ',') split
                WHERE   split.item in 
                (SELECT * from dbo.fnSplit(Replace(@Keywords, '''', ''''''), ','))
           )
          )
         )
...