Результаты заказа SQL по количеству совпадающих полей - PullRequest
3 голосов
/ 17 сентября 2009

Немного сложного вопроса SQL здесь.

В настоящее время у меня есть оператор SELECT, который соответствует нескольким полям, например:

SELECT field1, field2, field3, field4, field5
FROM table
WHERE field1 = 'variable 1'  
AND field2 = 'variable 2' 
AND field3 = 'variable 3' 
AND field4 = 'variable 4' 
AND field5 = 'variable 5' 

Я бы хотел изменить оператор так, чтобы он использовал вместо И AND, чтобы он выбирал все записи, соответствующие любому из полей.

Следующим шагом является ранжирование результатов с использованием системы подсчета очков.

If field 1 was matched then 1000 is added to the score
If field 2 was matched then 800 is added to the score
If field 3 was matched then 600 is added to the score
If field 4 was matched then 10 is added to the score
If field 5 was matched then 1 is added to the score

Итак ...

Матч 1 - Если поле 2 и поле 3 совпадают, то счет будет 1400

Матч 2 - Если поля 1 и 4 совпадают, то счет будет 1010

Матч 1 будет в верхней части результатов.

Любая помощь с некоторым SQL для достижения этой цели будет очень признательна.

Ответы [ 6 ]

5 голосов
/ 17 сентября 2009

TRY:

SELECT
    ....
    FROM ....

    ORDER BY
        (CASE WHEN field1 = 'variable 1' THEN 1000 ELSE 0 END
        +CASE WHEN field2 = 'variable 2' THEN 800 ELSE 0 END
        +CASE WHEN field3 = 'variable 3' THEN 600 ELSE 0 END
        +CASE WHEN field4 = 'variable 4' THEN 10 ELSE 0 END
        +CASE WHEN field5 = 'variable 5' THEN 1 ELSE 0 END
        ) DESC
3 голосов
/ 17 сентября 2009

Если вам нужно сделать все это за один выбор, то это должно быть что-то ужасное:

SELECT field1, field2, field3, field4, field5
FROM table
WHERE field1 = 'variable 1'  
 OR field2 = 'variable 2' 
 OR field3 = 'variable 3' 
 OR field4 = 'variable 4' 
 OR field5 = 'variable 5'
ORDER BY (Case when field1 = 'variable 1' then 1000 else 0 end
        + Case when field2 = 'variable 2' then 800 else 0 end
        + Case when field3 = 'variable 3' then 600 else 0 end
        + Case when field4 = 'variable 4' then 10 else 0 end
        + Case when field5 = 'variable 5' then 1 else 0 end) DESC

edit: вы также можете поместить секцию из нескольких регистров в SELECT в качестве поля вывода, если вы хотите, чтобы результат выводился. Затем вы можете заказать его, указав псевдоним или индекс столбца (как Янник М. делает ниже)

Возможно, более удачным решением будет разбить его на несколько запросов, при этом первый выбирает базовые данные во временную таблицу, а затем последующие запросы сканируют временную таблицу для корректировки значений оценки. Но в зависимости от вашей среды, это может быть не вариант.

2 голосов
/ 17 сентября 2009

Как насчет этого:

SELECT field1, field2, field3, field4, field5
FROM table
WHERE field1 = 'variable 1'  
OR field2 = 'variable 2' 
OR field3 = 'variable 3' 
OR field4 = 'variable 4' 
OR field5 = 'variable 5'
ORDER BY
  CASE WHEN field1 = 'variable 1' THEN 1000 ELSE 0 END +
  CASE WHEN field2 = 'variable 2' THEN 800 ELSE 0 END +
  CASE WHEN field3 = 'variable 3' THEN 600 ELSE 0 END +
  CASE WHEN field4 = 'variable 4' THEN 10 ELSE 0 END +
  CASE WHEN field5 = 'variable 5' THEN 1 ELSE 0 END
DESC
2 голосов
/ 17 сентября 2009

Используйте выражение CASE для создания счета:

CASE WHEN field1 = 'variable 1' THEN 1000 ELSE 0 END +
CASE WHEN field2 = 'variable 2' THEN  800 ELSE 0 END +
...
AS score

И тогда вы можете заказать по счету (и посмотреть, если это актуально). Или просто ЗАКАЗАТЬ сложное выражение, как в других ответах.

1 голос
/ 17 сентября 2009
SELECT field1, field2, field3, field4, field5,
  (CASE WHEN field1 = 'variable 1' THEN 1000 ELSE 0 END +
  CASE WHEN field2 = 'variable 2' THEN 800 ELSE 0 END +
  CASE WHEN field3 = 'variable 3' THEN 600 ELSE 0 END +
  CASE WHEN field4 = 'variable 4' THEN 10 ELSE 0 END +
  CASE WHEN field5 = 'variable 5' THEN 1 ELSE 0 END) as score
FROM table
ORDER BY 6 DESC;


+------+------+------+------+------+-------+
| f1   | f2   | f3   | f4   | f5   | score |
+------+------+------+------+------+-------+
|    1 |    2 | NULL | NULL | NULL |  1800 |
| NULL |    2 | NULL | NULL | NULL |   800 |
| NULL | NULL |    3 | NULL |    5 |   601 |
+------+------+------+------+------+-------+
3 rows in set (0.00 sec)
0 голосов
/ 17 сентября 2009

На мой взгляд, лучший способ сделать это - один агрегированный запрос - если это отвечает на ваш вопрос. Код будет выглядеть примерно так:

SELECT
    SUM(CASE WHEN FIELD1 = 'VARIABLE 1' THEN 1000 ELSE 0 END) F1FIND
,   SUM(CASE WHEN FIELD2 = 'VARIABLE 2' THEN 800 ELSE 0 END) F2FIND
,   SUM(CASE WHEN FIELD3 = 'VARIABLE 3' THEN 600 ELSE 0 END) F3FIND
,   SUM(CASE WHEN FIELD4 = 'VARIABLE 4' THEN 10 ELSE 0 END) F4FIND
,   SUM(CASE WHEN FIELD5 = 'VARIABLE 5' THEN 1 ELSE 0 END) F5FIND
FROM
    TABLE
;

И если вы просто хотите вернуть единичную оценку за определенный фактор, вы можете выполнить такой запрос:

SELECT
    F1FIND+F2FIND+F3FIND+F4FIND+F5FIND AS TOTAL_FIND
FROM
    ([ABOVE QUERY])
WHERE
    FACTOR = 'SOMETHING'
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...