Mysql sql如何将两个表中的三个查询合并为一个查询
我有以下两个表格: 表1Mysql sql如何将两个表中的三个查询合并为一个查询,mysql,sql,Mysql,Sql,我有以下两个表格: 表1 id name --------- A3 B2 A3 B400 A5 B100 A7 B200 A8 B6 A8 B2 A8 B3 和表2 id name company ------------------- A1 company1 A2 company2 A3 B1 company3 A4 company4 A5 B2 company5 A6 c
id name
---------
A3 B2
A3 B400
A5 B100
A7 B200
A8 B6
A8 B2
A8 B3
和表2
id name company
-------------------
A1 company1
A2 company2
A3 B1 company3
A4 company4
A5 B2 company5
A6 company6
A7 B3 company7
A8 B4 company8
A9 company9
A10 B6 company10
我启动了三个查询来获得我想要的,但是有三个查询。我的问题是如何在一个查询中以更高效的方式完成所有这些工作
查询1:
SELECT DISTINCT t1.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id
group by ID
SELECT DISTINCT t2.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.name = t2.name
group by ID
SELECT t1.name as ID,
t1.name as Company,
'NOT FOUND' AS status
FROM table1 t1
WHERE t1.name NOT IN (SELECT t2.name
FROM table2 t2)
GROUP BY ID
查询1结果:
查询2:
SELECT DISTINCT t1.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id
group by ID
SELECT DISTINCT t2.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.name = t2.name
group by ID
SELECT t1.name as ID,
t1.name as Company,
'NOT FOUND' AS status
FROM table1 t1
WHERE t1.name NOT IN (SELECT t2.name
FROM table2 t2)
GROUP BY ID
查询2结果:
查询3:
SELECT DISTINCT t1.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id
group by ID
SELECT DISTINCT t2.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.name = t2.name
group by ID
SELECT t1.name as ID,
t1.name as Company,
'NOT FOUND' AS status
FROM table1 t1
WHERE t1.name NOT IN (SELECT t2.name
FROM table2 t2)
GROUP BY ID
查询3结果:
最终结果输出如下所示:
ID Company Status
---------------------------
A3 company3 FOUND
A5 company5 FOUND
A7 company7 FOUND
A8 company8 FOUND
A10 company10 FOUND
B100 B100 NOT FOUND
B200 B200 NOT FOUND
B400 B400 NOT FOUND
注意:A5
和A7
会在第一个查询结果和第二个查询结果中弹出!所以我们只需要保留一个
如有必要,请给出一些解释:
我们从表1获得唯一id
s列表,并从表2获得相应的公司。我们对表1的第二列执行类似的查询:我们从表1中查找第二列的值,即名称
,在表2的第二列中,如果我们找到它,那么我们从表2中得到相应的id
和公司
,但是如果前面的查询中已经存在id
,那么我们将删除它,无需重复它。第三,如果我们在name
fromtable 2中的name
中没有找到name
的值,那么我们就没有任何相应的id
或company
,因此我们将name
的值同时作为id
和company
属性。一般来说,如果我们在表1中从表2中找到id
和名称
s,那么我们会给他们状态已找到
如果未找到,未找到
提前谢谢
顺便说一句,我已经使用union尝试了两次,但是查询需要很长时间,而且效率不高。尝试union DISTINCT,如:
SELECT DISTINCT t1.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id
group by ID
union distinct
SELECT DISTINCT t2.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.name = t2.name
group by ID
union distinct
SELECT t1.name as ID,
t1.name as Company,
'NOT FOUND' AS status
FROM table1 t1
WHERE t1.name NOT IN (SELECT t2.name
FROM table2 t2)
GROUP BY ID
您的查询有些不清楚,因为它们不应该像您显示的那样执行(因为select
包含不在groupby
中的非聚合)。但是根据你对你想做什么的解释
您可以使用外部联接,然后使用案例逻辑和/或合并来确定在每个案例中使用哪个值
SELECT DISTINCT
coalesce(t2_id.id, t2_name.id, t1.name) as ID
, coalesce(t2_id.company, t2_name.company, t1.name) as Conpany
, case when t2_id.id is not null or t2_name.name is not null
then 'FOUND'
else 'NOT FOUND'
end status
FROM table1 t1
LEFT JOIN table2 t2_id
ON t1.id = t2_id.id
LEFT JOIN table2 t2_name
ON t1.name = t2_name.name
请注意,我使用了DISTINCT
,以确保同一行不会多次出现;但这可能会根据数据返回ID的多行(具有不同的公司值)。我不太清楚是什么意思,因为在问题中公布的三个查询中,DISTINCT
和groupby
的用法对我来说似乎不合适。我想你可以使用如下查询:
SELECT DISTINCT IF(name2 IS NULL, name, ID) AS ID,
IF(name2 IS NULL, name, Company) AS Company,
IF(name2 IS NULL, 'NOT FOUND', 'FOUND') AS Status
FROM (
SELECT DISTINCT
CASE
WHEN t1.id = t2.id THEN t1.id
WHEN t1.name = t2.name THEN t2.id
ELSE t1.id
END AS ID,
CASE
WHEN t1.id = t2.id THEN t2.company
WHEN t1.name = t2.name THEN t2.company
ELSE t1.name
END AS Company,
t1.name,
(SELECT Table2.name
FROM Table2
WHERE Table2.name = t1.name LIMIT 1) AS name2
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 ON (t1.id = t2.id) OR (t1.name = t2.name)) AS t
ORDER BY ID;
该查询使用单个左联接操作加上相关子查询
这些要求已经够令人困惑的了,可能值得重新评估您的数据模型。我认为UNION
解决方案是您可能修改为使用UNION ALL
以提高效率的最佳选择
我确实设计了一个基于互斥锁的黑客程序,它可能与本页上的任何其他查询一样存在许多微妙的问题
select
coalesce(t2.id, t1.name) AS ID,
coalesce(t2.company, t1.name) AS Company,
if(isnull(t2.id), 'NOT FOUND', 'FOUND') as Status
from (select 0 as mutex union select 1) as m
left join table1 as t1 on 1 = 1
left join table2 as t2 on t1.name = t2.name or (t1.id = t2.id and mutex)
group by coalesce(t2.id, t1.name)
也就是说,请仔细测试这些查询,并查看您的数据和结果。根据您的输入数据,有很大的出错空间 你是说只有标题应该是大写字母吗?或者别的什么?@GiorgosBetsos确切地说,因为我们找不到任何对应的ID或公司,我们将该名称(即B100)同时作为ID和公司。我知道这可以通过联合
实现,但它根本没有效率。这需要很多时间。FWIW,UNION ALL
可能比UNION
更有效,因为它跳过了重复消除。但这不是我个人会使用的方法;你也可以看看我的建议答案。联合所有更有效,但不要消除重复。让我试试你的答案,然后看看分组的目的是什么。事实上,我没有把这些分组的s,我只得到一个结果!如果我包括它们,我会得到该查询的所有结果。实际上,使用合并和案例逻辑的想法很好,但它会返回大量重复的结果。我们需要唯一的值。同样,我不确定重复数据消除规则对我来说是否清楚,但如果你能澄清它们,我可以改进查询。最简单的事情-如果所有字段中的重复项都相同,那么只需说SELECT DISTINCT
,而不是像在原始查询中那样说SELECT
。要使groupby
按照您在前面的注释中描述的方式运行,您运行的查询与发布的查询必须有所不同。也许您在第二列上使用了聚合函数(如MIN或MAX)?这将是另一种重复数据消除策略,它将确保每个ID只显示一次(并且只选择其中一个名称来匹配它)……在某些情况下,您似乎必须再次加入表1
,才能同时找到和未找到。例如,如果您将Table2的“B3”单元格设为空,则最终结果中缺少ID“A7”。这太神奇了!谢谢是否可以将每个列的计数添加到另一列?这是它想要的。计算ID在column1-table1中被重复的次数,再加上该次数,“name”(在column1中有其相应的ID)被重复的次数,如果它没有相应的ID,那么它自己被计算在table1的第二列中被重复的次数。@marcel,这是另一个问题。试着为这个要求写一篇单独的帖子。@ebyrob仔细看后,你的评论是不正确的。如果您提到OP中引用的三个查询都不会返回带有Id=A7的table1
记录。我向她发布了新问题