Левое объединение будет нулевым в MySQL - PullRequest
0 голосов
/ 22 февраля 2019

Я ищу способ создания функции относительной релевантности при поиске значений в двух (или более) разных таблицах.Итак, у меня есть такие таблицы

table1:

id weight
1  0.1
2  0.15
3  0.12
6  0.21

table2:

id weight
3  0.09
6  0.2
8  0.1
11 0.13

Мне нужно получить функцию релевантности из этих двух таблиц путем их объединения.Те же идентификаторы строк получат 10-кратную релевантность, а строки с идентификаторами только из одной таблицы получат «весовую» релевантность.

Вот промежуточная таблица, которую мне нужно получить (и мой вопрос - КАК сделать такую ​​таблицу):

id1  weight1  id2  weight2
1    0.1      null null
2    0.15     null null
3    0.12     3    0.09
6    0.21     6    0.2
null null     8    0.1
null null     11   0.13

Используя эту таблицу, я могу вычислить релевантность, что мне нужно, но проблема состоит в том, чтобы создать такую ​​таблицу из этих двух.Не могли бы вы мне помочь?

Я пытался с LEFT JOIN, STRAIGHT_JOIN, LEFT OUTER JOIN, но они дают совершенно разные результаты.

Редактировать: Если это имеет значение, я в настоящее время предусматриваю поиск финальной таблицыкак то так:

id relevance
 1 0.1
 2 0.15
 3 2.1
 6 4.1
 8 0.1
11 0.13

Ответы [ 4 ]

0 голосов
/ 22 февраля 2019

Вот несколько примеров:

create table Table1 (
 id int primary key not null,
 weight decimal(10,2) not null default 0
);
create table Table2 (
 id int primary key not null,
 weight decimal(10,2) not null default 0
);
insert into Table1 (id, weight) values
 (1, 0.10)
,(2, 0.15)
,(3, 0.12)
,(6, 0.21)
;
insert into Table2 (id, weight) values
 (3,  0.09)
,(6,  0.20)
,(8,  0.10)
,(11, 0.13)
;
select 
id12.id as id,
t1.id as id1,
t1.weight as weight1,
t2.id as id2,
t2.weight as weight2
from (select id from Table1 union select id from Table2) id12
left join Table1 t1 on t1.id = id12.id
left join Table2 t2 on t2.id = id12.id
;
id |  id1 | weight1 |  id2 | weight2
-: | ---: | ------: | ---: | ------:
 1 |    1 |    0.10 | <em>null</em> |    <em>null</em>
 2 |    2 |    0.15 | <em>null</em> |    <em>null</em>
 3 |    3 |    0.12 |    3 |    0.09
 6 |    6 |    0.21 |    6 |    0.20
 8 | <em>null</em> |    <em>null</em> |    8 |    0.10
11 | <em>null</em> |    <em>null</em> |   11 |    0.13
select 
id12.id as id,
coalesce(t1.weight,0) + coalesce(t2.weight,0) as relevance
from (select id from Table1 union select id from Table2) id12
left join Table1 t1 on t1.id = id12.id
left join Table2 t2 on t2.id = id12.id
order by id12.id;
id | relevance
-: | --------:
 1 |      0.10
 2 |      0.15
 3 |      0.21
 6 |      0.41
 8 |      0.10
11 |      0.13
select id, sum(weight) as relevance
from
(
 select id, weight from Table1
 union all 
 select id, weight from Table2
) q
group by id
order by id;
id | relevance
-: | --------:
 1 |      0.10
 2 |      0.15
 3 |      0.21
 6 |      0.41
 8 |      0.10
11 |      0.13

db <> скрипка здесь

2-й и 3-й запросы возвращают один и тот же результат.
Что лучше?
Это будет зависеть от того, сколько дополнительных полей и / или дополнительных вычислений требуется.

0 голосов
/ 22 февраля 2019
SELECT id
     , SUM(weight) * CASE WHEN COUNT(*)=1 THEN 1 ELSE 10 END relevance 
  FROM
     ( SELECT id
            , weight 
         FROM table1 
        UNION 
          ALL 
       SELECT id
            , weight 
         FROM table2
     ) x
 GROUP 
    BY id;
+----+-----------+
| id | relevance |
+----+-----------+
|  1 |      0.10 |
|  2 |      0.15 |
|  3 |      2.10 |
|  6 |      4.10 |
|  8 |      0.10 |
| 11 |      0.13 |
+----+-----------+
0 голосов
/ 22 февраля 2019

Мы можем использовать хранимые процедуры и временные таблицы, чтобы получить решение

CREATE PROCEDURE GetReleavance()
BEGIN
Create TEMPORARY TABLE tmpList ENGINE=MEMORY
SELECT id, weight from t1
union all 
SELECT id, weight from t2
union all 
SELECT id, weight from t3;

select id, sum(weight)* POW(10,COUNT(1)-1) as relevance 
from tmpList 
group by id;

DROP TEMPORARY TABLE IF EXISTS tmpList;

END

В процедуре создаем временную таблицу со всеми идентификаторами и весом из другой таблицы и получаем сумму (вес) на основе идентификатора.

Вызовите хранимую процедуру, используя

CALL GetReleavance()

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

0 голосов
/ 22 февраля 2019

Для этого вы можете использовать FULL OUTER JOIN, например:

SELECT t1.id AS id1, t1.weight AS weight1, t2.id AS id2, t2.weight AS weight2
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id
UNION
SELECT t1.id AS id1, t1.weight AS weight1, t2.id AS id2, t2.weight AS weight2
FROM table1 t1 RIGHT JOIN table2 t2 ON t1.id = t2.id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...