Trying to perform MINUS operation in MySQL

前端 未结 6 409
野性不改
野性不改 2020-11-29 10:21

I am trying to perform a MINUS operation in MySql.I have three tables:

  1. one with service details
  2. one table with states that a service is o
相关标签:
6条回答
  • 2020-11-29 10:49

    MySQL Does not supports MINUS or EXCEPT,You can use NOT EXISTS , NULL or NOT IN.

    0 讨论(0)
  • 2020-11-29 10:57

    An anti-join pattern is the approach I typically use. That's an outer join, to return all rows from query_1, along with matching rows from query_2, and then filtering out all the rows that had a match... leaving only rows from query_1 that didn't have a match. For example:

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

    To emulate the MINUS set operator, we'd need the join predicate to compare all columns returned by q1 and q2, also matching NULL values.

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

    Also, To fully emulate the MINUS operation, we'd also need to remove duplicate rows returned by q1. Adding the DISTINCT keyword would be sufficient to do that.

    0 讨论(0)
  • 2020-11-29 10:59

    In case the tables are huge and are similar, one option is to save the PK to new tables. Then compare based only on the PK. In case you know that the first half is identical or so add a where clause to check only after a specific value or date .

    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 )
    
    0 讨论(0)
  • 2020-11-29 11:02

    The tables have to have the same columns, but I think you can achieve what you are looking for with EXCEPT... except that EXCEPT only works in standard SQL! Here's how to do it in 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/

    Standard SQL

    SELECT * FROM Servicing_States
    EXCEPT
    SELECT * FROM Exception;
    
    0 讨论(0)
  • 2020-11-29 11:04

    Here's my two cents... a complex query just made it work, originally expressed with Minus and translated for MySql

    With MINUS:

    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;
    

    With NOT EXISTS

    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
    
    0 讨论(0)
  • 2020-11-29 11:11

    MySql does not recognise MINUS and INTERSECT, these are Oracle based operations. In MySql a user can use NOT IN as MINUS (other solutions are also there, but I liked it lot). Example:

    select a.id 
    from table1 as a 
    where <condition> 
    AND a.id NOT IN (select b.id 
                     from table2 as b 
                     where <condition>);
    
    0 讨论(0)
提交回复
热议问题