简体   繁体   中英

Ranking SQL Server Query results

Is there a way in SQL Server to rank rows based on the values in the WHERE clause?

For instance:

SELECT *
FROM Foo
WHERE 
  Bar1 = true AND
  Bar2 = true OR
  Bar3 = false

The best result in this case would be a row where Bar1 = true, Bar2 = true and Bar3 = false. A row where Bar1 = true, Bar2 = true and Bar3 = true would score lower because Bar3 is different.

To make it even more complicated. The WHERE clause is dynamic, I don't know exactly which columns will appear in the query. So the next query could be:

SELECT *
FROM Foo
WHERE 
  Bar1 = false OR
  Bar3 = true OR
  Bar4 = True

How can I apply ranking to those queries?

Can this be done within the query or is it better to do this in C#?

You can order the results by the number of where clauses that match:

order by ((case when Bar1 = true AND Bar2 = true then 1 else end) +
          (case when Bar3 = false then 1 else 0 end)
         ) desc

You could also add this to a field in the select . If you are dynamically creating the where , you would have to do the same thing for the order by (or select variable).

I would advise you to do this in the database, because replicating the logic between SQL and C# seems like a maintenance nightmare.

WITH CTE 
     AS (SELECT T.*, 
                RN = ROW_NUMBER() 
                       OVER ( 
                         ORDER BY BAR1 ASC, BAR2 ASC, BAR3 DESC) 
         FROM   DBO.TABLENAME T) 
SELECT * 
FROM   CTE 
ORDER  BY RN 

You could give each clause a score of 1 if it is satisfied and 0 if it is not satisfied. And then you can order by the sum of scores.

Something like:

SELECT *
FROM Foo
ORDER BY cast((Bar1 = true) as int)
       + cast((Bar2 = true OR Bar3 = false) as int)
DESC

Don't know what do you mean by true in SQL Server. If you Bars are bit columns, you can rank like this:

select *
from Foo
order by
    case
       when Bar1 = 1 and Bar2 = 1 and Bar3 = 0 then 0
       else 1
    end asc

if it's strings:

select *
from Foo
order by
    case
       when Bar1 = 'true' and Bar2 = 'true' and Bar3 = 'false' then 0
       else 1
    end asc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM