sql如何将两个表中的三个查询合并为一个查询

时间:2016-12-20 14:38:31

标签: 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          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

查询1结果:

ID  Company     Status
-----------------------
A3  company3    FOUND
A5  company5    FOUND
A7  company7    FOUND
A8  company8    FOUND

查询2:

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

查询2结果:

ID  Company     Status
-----------------------
A5  company5    FOUND
A10 company10   FOUND
A7  company7    FOUND

查询3:

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
-----------------------
B400    B400    NOT FOUND
B100    B100    NOT FOUND
B200    B200    NOT FOUND

和最终结果输出如下:

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

注意:A5A7在第一个查询结果中弹出,也在第二个查询结果中弹出!所以我们只需要保留一个。

如果需要,可以进行一些解释: 我们从 table1 获取唯一id的列表,从 table2 获取相应的company。我们对 table1 的第二列执行了类似的查询:我们在第二列中查找 table1 中第二列的值,即name table2 ,如果我们找到它,那么我们会从 table2 获得相应的idcompany,但是如果{{1}已经存在于我们之前的查询中然后我们放弃它,不需要重复它。第三,如果我们在 table2 id中找不到 table1 name值,那么我们没有相应的nameid,因此我们将company值归为nameid。一般情况下,如果我们在 table2 中找到 table1 中的companyid,那么我们会为其提供状态name如果没有,FOUND

提前致谢

顺便说一句,我已经尝试了两次使用NOT FOUND,但查询需要很长时间而且效率不高。

4 个答案:

答案 0 :(得分:3)

这些要求令人困惑,可能值得重新评估您的数据模型。我认为UNION解决方案是您最好的选择,可以修改为使用UNION ALL来提高效率。

我确实整理了一个基于互斥锁的hack,它可能会出现与此页面上任何其他查询一样多的微妙问题。

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)

也就是说,请仔细测试这些查询并查看您的数据和结果。根据您的输入数据,存在很大的错误空间。

答案 1 :(得分:2)

尝试使用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

答案 2 :(得分:2)

您的查询有些不清楚,因为它们不应该像您显示的那样执行(由于sess.run(y_, feed_dict={x: [np.flatten(image_you_loaded_in)]}) 包含不在select中的非聚合)。但根据你对你要做的事情的解释......

您可以使用外连接,然后使用案例逻辑和/或合并来确定在每种情况下使用哪个值。

group by

请注意,我使用了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 来确保完全相同的行不会多次出现;但这可能会为ID(具有不同的公司值)返回多行,具体取决于数据。我无法确切地说出是什么意思,因为在问题中发布的三个查询中DISTINCTDISTINCT的使用似乎并没有为我增加。

答案 3 :(得分:1)

我认为您可以使用如下查询:

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;

查询使用单个LEFT JOIN操作加上相关子查询。

Demo here