左联接在MySQL中将为空

时间:2019-02-22 09:38:29

标签: mysql mysqli left-join relevance

我正在寻找一种在两个(或多个)不同表中查找值时创建相对相关性函数的方法。所以我有这样的桌子

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

我需要通过合并这两个表来获得关联功能。相同的行ID将获得10倍的相关性,而仅来自一个表的具有ID的行将具有“权重”相关性。

这是我需要获取的中间表(我的问题是如何制作这样的表):

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 :(得分:2)

您可以为此使用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;

答案 1 :(得分:1)

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 |
+----+-----------+

答案 2 :(得分:1)

以下是一些示例:

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 | null |    null
 2 |    2 |    0.15 | null |    null
 3 |    3 |    0.12 |    3 |    0.09
 6 |    6 |    0.21 |    6 |    0.20
 8 | null |    null |    8 |    0.10
11 | null |    null |   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 <>提琴here

第二和第三查询返回相同的结果。
哪个更好?
那将取决于需要多少额外的字段和/或额外的计算。

答案 3 :(得分:0)

我们可以使用存储过程和临时表来获取解决方案

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

在此过程中,创建一个具有所有ID和不同表中的权重的临时表,并根据ID获得sum(weight)。

使用调用存储过程

CALL GetReleavance()

您可以将Union全部设置为所需的表数,也不会对性能产生重大影响。