试图在MySQL中执行MINUS操作

时间:2015-07-14 03:50:32

标签: mysql

我正在尝试在MySql中执行MINUS操作。我有三个表:

  1. 一个有服务详情
  2. 一个表格中提供服务的表格
  3. 另一个表(基于zipcode和state)显示未提供此服务的位置。
  4. 我能够分别获得这两个选择查询的输出。但我需要一个组合语句,将输出作为 ' SELECT query_1 - SELECT query_2'。

    Service_Details表 Service_Code(PK)服务名称

    Servicing_States表 Service_Code(FK)州国家PK(Service_Code,州,国家)

    例外表 Service_Code(FK)Zipcode状态PK(Service_Code,Zipcode,State)

6 个答案:

答案 0 :(得分:18)

MySql无法识别 MINUS INTERSECT ,这些是基于Oracle的操作。在MySql中,用户可以使用NOT IN作为MINUS其他解决方案也在那里,但我喜欢它很多)。 例如:

select a.id 
from table1 as a 
where <condition> 
AND a.id NOT IN (select b.id 
                 from table2 as b 
                 where <condition>);

答案 1 :(得分:6)

MySQL不支持MINUS或EXCEPT,您可以使用NOT EXISTS,NULL或NOT IN。

答案 2 :(得分:1)

这些表必须具有相同的列,但我认为您可以使用EXCEPT来实现您的目标...除了EXCEPT仅适用于标准SQL!以下是在MySQL中如何做到这一点:

SELECT * FROM Servicing_states ss WHERE NOT EXISTS 
   ( SELECT * FROM Exception e WHERE ss.Service_Code = e.Service_Code);

http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/

标准SQL

SELECT * FROM Servicing_States
EXCEPT
SELECT * FROM Exception;

答案 3 :(得分:1)

反连接模式是我通常使用的方法。这是一个外连接,用于返回query_1中的所有行,以及来自query_2的匹配行,然后过滤掉所有匹配的行...只留下query_1中没有匹配的行。例如:

   SELECT q1.* 
     FROM ( query_1 ) q1
     LEFT
     JOIN ( query_2 ) q2 
       ON q2.id = q1.id 
    WHERE q2.id IS NULL

要模拟MINUS集合运算符,我们需要连接谓词来比较q1和q2返回的所有列,也匹配NULL值。

       ON q1.col1 <=> q2.col2
      AND q1.col2 <=> q2.col2
      AND q1.col3 <=> q2.col3
      AND ... 

此外,要完全模拟MINUS操作,我们还需要删除q1返回的重复行。添加DISTINCT关键字就足够了。

答案 4 :(得分:1)

这是我的两分钱...一个复杂的查询使它起作用了,最初是用Minus表示并翻译成MySql

带减号:

select distinct oi.`productOfferingId`,f.name 
from t_m_prod_action_oitem_fld f
     join t_m_prod_action_oitem oi 
    on f.fld2prod_action_oitem = oi.oid;
minus
select
  distinct r.name,f.name
from t_m_prod_action_oitem_fld f
     join t_m_prod_action_oitem oi 
    on f.fld2prod_action_oitem = oi.oid
     join t_m_rfs r 
    on r.name = oi.productOfferingId
     join t_m_attr a 
    on a.attr2rfs = r.oid and f.name = a.name;

不存在

select distinct oi.`productOfferingId`,f.name 
from t_m_prod_action_oitem_fld f
     join t_m_prod_action_oitem oi 
    on f.fld2prod_action_oitem = oi.oid
where not exists (
select
  r.name,f.name
from t_m_rfs r 
     join t_m_attr a 
    on a.attr2rfs = r.oid   
where r.name = oi.productOfferingId and f.name = a.name

答案 5 :(得分:0)

如果表很大且相似,则一种方法是将PK保存到新表中。然后仅根据PK进行比较。如果您知道前半部分相同,或者添加一个where子句以仅在特定值或日期之后进行检查。

create table _temp_old ( id int NOT NULL PRIMARY KEY )

create table _temp_new ( id int NOT NULL PRIMARY KEY )

### will take some time
insert into _temp_old ( id ) 
select id from _real_table_old  

### will take some time
insert into _temp_new ( id ) 
select id from _real_table_new

### this version should be much faster
select id  from _temp_old to where not exists ( select id from _temp_new tn where to.id = tn.id)

### this should be much slower
select id  from _real_table_old rto where not exists ( select id from _real_table_new rtn where rto.id = rtn.id )