Search code examples
sql-serverfull-text-searchfull-text-indexingfreetext

SQL Server full text search on column with alias


I am using full-text search, its working fine on a direct column of table but not on a derived/aliased column.

SELECT ExpectationId
    ,ExpectationName
    ,(
       CASE 
          WHEN ExpectationOrganization_OrganizationId IS NOT NULL
                THEN (
                       SELECT OrganizationName
                       FROM Organizations
                       WHERE OrganizationId = ExpectationOrganization_OrganizationId
                       )
          WHEN ExpectationBeneficiary_BeneficiaryId IS NOT NULL
                THEN (
                       SELECT BeneficiaryName
                       FROM Beneficiaries
                       WHERE BeneficiaryId = ExpectationBeneficiary_BeneficiaryId
                       )
          ELSE (
                    SELECT TeamName
                    FROM Teams
                    WHERE TeamId = ExpectationTeam_TeamId
                    )
          END
       ) AS ParentName
FROM Expectations
WHERE
    FREETEXT(ExpectationName, @Keyword) ---Working
    OR FREETEXT(ParentName, @Keyword) ---Not working

All these columns ExpectationName, OrganizationName, BeneficiaryName, TeamName are full-text indexed.

How can I make it work for ParentName column?


Solution

  • You need to create a VIEW based on your query first then add a Full-Text index to it which will include the ParentName column. Without the Full-Text index over a column being searched neither FREETEXT nor CONTAINS will work.

    Something like that should help you:

    CREATE VIEW ExpectationsView AS
    SELECT ExpectationId
        ,ExpectationName
        ,(
           CASE 
              WHEN ExpectationOrganization_OrganizationId IS NOT NULL
                    THEN (
                           SELECT OrganizationName
                           FROM Organizations
                           WHERE OrganizationId = ExpectationOrganization_OrganizationId
                           )
              WHEN ExpectationBeneficiary_BeneficiaryId IS NOT NULL
                    THEN (
                           SELECT BeneficiaryName
                           FROM Beneficiaries
                           WHERE BeneficiaryId = ExpectationBeneficiary_BeneficiaryId
                           )
              ELSE (
                        SELECT TeamName
                        FROM Teams
                        WHERE TeamId = ExpectationTeam_TeamId
                        )
              END
           ) AS ParentName
    FROM Expectations
    GO
    
    -- This index is needed for FTS index.
    -- Note, I trust ExpectationId column is unique in your SELECT above,
    -- if it's not, the below CREATE INDEX will fail and you will need to provide 
    -- a new column to your VIEW which will uniquely identify each row, then use 
    -- that PK-like column in the below index
    CREATE UNIQUE CLUSTERED INDEX PK_ExpectationsView   
        ON ExpectationsView (ExpectationId);  
    GO  
    
    CREATE FULLTEXT CATALOG fts_catalog;  
    GO  
    CREATE FULLTEXT INDEX ON ExpectationsView  
     (
        ExpectationName Language 1033,   
        ParentName Language 1033
     )   
      KEY INDEX PK_ExpectationsView 
          ON fts_catalog;
          WITH (CHANGE_TRACKING = AUTO)
    GO  
    

    Once the Full-Text index which includes the relevant columns is there you can use FREETEXT or CONTAINS in queries:

    SELECT ExpectationId, ExpectationName, ParentName FROM ExpectationsView
        WHERE FREETEXT(ExpectationName, @Keyword) OR FREETEXT(ParentName, @Keyword)
    

    Note, the above code I've provided off the top of my head because I don't have data schema for your case so couldn't try running it. However, it should give you the general idea on how to proceed. HTH.