SQL只获得最高排名

时间:2018-02-08 16:32:51

标签: sql sql-server

我正在尝试对用户搜索字词进行排名,并仅返回最相关的搜索。

请参阅下面的查询。

SELECT * FROM
        (
            SELECT 
                c.ContractorId,
                c.CompanyName,
                co.County,
                t.Town,
                s.[Service],
                s.ServiceId,

                CASE
                    WHEN c.CompanyName = @CompanyName THEN 1
                    WHEN ct.TownId = @TownId AND cs.ServiceId = @ServiceId THEN 1
                    WHEN cc.CountyId = @CountyId AND cs.ServiceId = @ServiceId THEN 1
                    WHEN cc.CountyId = @CountyId AND cs.ServiceId = @ServiceId THEN 1
                    WHEN ct.TownId = @TownId AND cc.CountyId = @CountyId THEN 2
                    WHEN ct.TownId IS NULL AND cc.CountyId IS NULL AND cs.ServiceId = @ServiceId THEN 3
                    WHEN @TownId IS NULL AND @CountyId IS NULL AND cs.ServiceId = @ServiceId THEN 3
                END AS 'Rank'

            FROM
                Contractors.Contractor c 
            LEFT JOIN
                Contractors.ContractorTown ct ON c.ContractorId = ct.ContractorId
            LEFT JOIN
                Geographical.Town t ON ct.TownId = t.TownId
            LEFT JOIN 
                Contractors.ContractorCounty cc ON c.ContractorId = cc.ContractorId
            LEFT JOIN
                Geographical.County co ON cc.CountyId = co.CountyId
            LEFT JOIN
                Contractors.ContractorService cs ON c.ContractorId = cs.ContractorId
            LEFT JOIN
                Contractors.[Service] s ON cs.ServiceId = s.ServiceId
            JOIN
                Contractors.ContractorLiability cl ON cl.ContractorId = c.ContractorId
            WHERE
                c.CompanyName = @CompanyName
                OR (ct.TownId = @TownId AND cs.ServiceId = @ServiceId)
                OR (cc.CountyId = @CountyId AND cs.ServiceId = @ServiceId)
                OR (ct.TownId = @TownId AND cc.CountyId = @CountyId)
                OR (ct.TownId IS NULL AND cc.CountyId IS NULL AND cs.ServiceId = @ServiceId)
                OR (cs.ServiceId = @ServiceId)) AS a

由此我尝试仅获得排名最高的结果,例如:

如果存在等级1,则返回仅为等级1的所有行。 如果存在等级2,则返回仅为等级2的所有行。 否则返回一切。

我不确定解决此问题的最佳方法 - 欢迎任何建议。

1 个答案:

答案 0 :(得分:0)

尝试将此添加到最终的 WHERE 语句中:

where...
...
and
case
when exists (select rank from table where rank=1) then rank=1
when exists (select rank from table where rank=2) then rank=2
else rank is not null
end

如果任何行的等级等于1,它应该将范围缩小到只有rank = 1的行,如果在1处没有行,则应该对2进行相同的操作。如果没有行的等级为1或2,那么它只是确保有一个排名值。

你试过临时桌吗?

CREATE TABLE #temp
(
ContractorId int,
    CompanyName varchar(255),
    County varchar(255),
    Town varchar(255),
    [Service] varchar(255),
    ServiceId int,
rank int
);

建立表格,然后

--REPLACE 'SELECT * FROM(' WITH
INSERT INTO #temp (ContractorId, CompanyName, County, Town, [Service], ServiceID, rank)
    SELECT 
            c.ContractorId,
            c.CompanyName,
            co.County,
            t.Town,
            s.[Service],
            s.ServiceId,
    ...

然后在新临时表上运行另一个查询。