尝试在MySQL中执行MINUS操作

u4vypkhs  于 2023-04-19  发布在  Mysql
关注(0)|答案(7)|浏览(226)

我试图在MySql中执行MINUS操作。我有三个表:
1.一个包含服务详细信息
1.一个包含提供服务的状态的表
1.另一个表(基于邮政编码和州)示出了不提供该服务的地方。
我可以分别获得这两个选择查询的输出。但是我需要一个组合语句,它的输出为'SELECT query_1 - SELECT query_2'。

Service_Details表Service_Code(主键)服务名称
Service_States表Service_Code(FK)State Country主键(Service_Code,State,Country)
异常表Service_Code(FK)Zipcode状态主键(Service_Code,Zipcode,State)

gwo2fgha

gwo2fgha1#

MySql不识别MINUSINTERSECT,这些是基于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>);
ppcbkaq5

ppcbkaq52#

MySQL不支持MINUSEXCEPT,您可以使用NOT EXISTSNULLNOT IN

ua4mk5z4

ua4mk5z43#

这里是我的两个美分…一个复杂的查询刚刚使它工作,最初表示为减和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
at0kjp5o

at0kjp5o4#

这些表必须有相同的列,但我认为你可以用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;
jyztefdp

jyztefdp5#

反连接模式是我通常使用的方法。这是一个外部连接,返回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集合运算符,我们需要连接 predicate 来比较q1和q2返回的所有列,也匹配NULL值。

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

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

4jb9z9bj

4jb9z9bj6#

如果表很大并且相似,一个选择是将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 )
ilmyapht

ilmyapht7#

select a1.loc from(select distinct(column)as loc from table1 where condition)as a1 where a1.loc not in(select b1.loc from(select distinct(column)as loc from table2 where condition)as b1);
它将在MySQL中给予'MINUS'功能:)

相关问题