1

I am creating a stored procedure in SQL Server as follows:

CREATE PROCEDURE [dbo].[SearchData] 
    @searchText varchar(500)
AS
BEGIN
    SET NOCOUNT ON

    SELECT TOP 50 
        s.[MaxRank] AS [Rank],
        sc.TaskSourceId,
        c.IndividualName,
        c.EntityName,
        c.Text
    FROM
        (SELECT
             MAX(s.Rank) AS MaxRank,
             MAX(c.CaptureId) AS MaxCaptureId,
             c.TaskSourceId
         FROM
             FreeTextTable(Data.SearchData,
                  (Identifier, IndividualName, EntityName, [Text]), @searchText) s
         JOIN
             Data.Capture c ON s.[Key] = c.CaptureId
         GROUP BY
             c.TaskSourceId) s
    JOIN
        Data.Capture c ON c.CaptureId = s.MaxCaptureId
    JOIN
        Data.Source sc ON c.TaskSourceId = sc.TaskSourceId
    ORDER BY
        s.MaxRank DESC
END

The above executes successfully but includes some results where the Text field is the only field with data, with the others being NULL. I want to add a condition that says that, in the returned results, IndividualName must not be null OR EntityName must not be null.

I'm having trouble figuring where to put this and the exact syntax.

2
  • 3
    You'll need a WHERE clause and use IS NOT NULL Commented Jan 11, 2017 at 15:53
  • 1
    In other words Where (IndividualName is not null OR EntityName is not null). Just a SQL translation from what you wrote Commented Jan 11, 2017 at 15:58

3 Answers 3

2

I assume you mean that one of the fields CAN be null. If so:

CREATE PROCEDURE [dbo].[SearchData] 
@searchText varchar(500)

AS BEGIN SET NOCOUNT ON

select top 50 s.[MaxRank] as [Rank],
    sc.TaskSourceId,
    c.IndividualName,
    c.EntityName,
    c.Text

from    (
    select  max(s.Rank) as MaxRank,
        max(c.CaptureId) as MaxCaptureId,
        c.TaskSourceId
    from    FreeTextTable(Data.SearchData,
           (Identifier, IndividualName, EntityName, [Text]),
               @searchText) s
    join    Data.Capture c
    on  s.[Key] = c.CaptureId
    group   by c.TaskSourceId
    ) s
join    Data.Capture c
on  c.CaptureId = s.MaxCaptureId
join   Data.Source sc
on     c.TaskSourceId = sc.TaskSourceId
where not (c.IndividualName is null and c.EntityName is null) -- excludes results where both are null
order   by s.MaxRank desc
END
Sign up to request clarification or add additional context in comments.

4 Comments

In other words IndividualName is not null OR EntityName is not null
@Prdp True, but when you start adding other conditions, this is much tidier and less likely to result in confusion.
Upvoted.. But I feel many find difficult to understanfd NOT operator when there is more than one condition involved inside NOT
(InvidiualName is not null OR EntityName is not null) (with the parens) should give best of both worlds, should it not?
2

You can do an isnull on both columns and check to make sure that value is not null, like this:

CREATE PROCEDURE [dbo].[SearchData] 
@searchText varchar(500)

AS BEGIN SET NOCOUNT ON

select top 50 s.[MaxRank] as [Rank],
    sc.TaskSourceId,
    c.IndividualName,
    c.EntityName,
    c.Text

from    (
    select  max(s.Rank) as MaxRank,
        max(c.CaptureId) as MaxCaptureId,
        c.TaskSourceId
    from    FreeTextTable(Data.SearchData,
           (Identifier, IndividualName, EntityName, [Text]),
               @searchText) s
    join    Data.Capture c
    on  s.[Key] = c.CaptureId
    group   by c.TaskSourceId
    ) s
join    Data.Capture c
on  c.CaptureId = s.MaxCaptureId
join   Data.Source sc
on     c.TaskSourceId = sc.TaskSourceId
where not isnull(c.IndividualName, c.EntityName) is null  
order   by s.MaxRank desc
END

4 Comments

Cool... never seen a sql construct like that not isnull(c.IndividualName, c.EntityName) is null... +1
While a clever and readable approach, how does this handle over large datasets? Also, sargable?
Good question John. I have used this approach before on pretty large datasets but I cannot say for sure whether it is sargable or not (my guess is that it is not).
It's not SARG (cannot use index on names).
0

You can also use these condition in the join condition.

CREATE PROCEDURE [dbo].[SearchData] 
@searchText varchar(500)

AS BEGIN SET NOCOUNT ON

select top 50 s.[MaxRank] as [Rank],
    sc.TaskSourceId,
    c.IndividualName,
    c.EntityName,
    c.Text
from    (
    select  max(s.Rank) as MaxRank,
        max(c.CaptureId) as MaxCaptureId,
        c.TaskSourceId
    from    FreeTextTable(Data.SearchData,
           (Identifier, IndividualName, EntityName, [Text]),
               @searchText) s
    join    Data.Capture c
    on  s.[Key] = c.CaptureId
    group by c.TaskSourceId
    ) s
join    Data.Capture c
on  c.CaptureId = s.MaxCaptureId AND (c.IndividualName IS NOT NULL OR c.EntityName IS NOT NULL)
join   Data.Source sc
on     c.TaskSourceId = sc.TaskSourceId
order by s.MaxRank desc

END

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.