1

I have two columns: amountFrom , amountTo in table shipping

Lets say I have these row data:

amountFrom | amountTo
-----------------------
0            15
16           30
31           50

Now I would like to add these three:

amountFrom | amountTo
-----------------------
15           22 (should fail, already exist (crosses range))
18           25 (should fail, already exist)
55           76 (should pass)

How can I make a correct sql query, that will run for each row i would like to insert, that will check if the "range" is available?

Example of what i tried

SELECT id FROM shipping WHERE amountFrom >= 15 AND amountTo <= 22

Above query returns no rows, which it should (if it was a correct query) since we dont want to make a new row with 15 and 22, as it will cross existing weight ranges

Karem
  • 17,615
  • 72
  • 178
  • 278

2 Answers2

1

You can try this (here with values 15 and 22) :

INSERT INTO t (amountFrom, amountTo)
 SELECT 15, 22
 WHERE NOT EXISTS (SELECT 1 FROM t WHERE 22 >= amountFrom AND 15 <= amountTo);

You can check the affected-rows value to see wether or not the row was actually inserted.

Eric Citaire
  • 4,355
  • 1
  • 29
  • 49
0

You don't have to do three separate inserts. You can do them all at once (at least with the data in your query).

The select statement to see which do not overlap is:

select t2.*
from table2 t2
where not exists (select 1
                  from table1 t1
                  where t1.amountFrom <= t2.amountTo and
                        t1.amountTo >= t2.amountFrom
                 );

Two ranges overlaps if one starts before the other ends, and the first ends after the other starts.

You put this into an insert as

insert into t1(amountFrom, amountTo)
    select t2.amountFrom, t2.amountTo
    from table2 t2
    where not exists (select 1
                      from table1 t1
                      where t1.amountFrom <= t2.amountTo and
                            t1.amountTo >= t2.amountFrom
                     );

EDIT:

If you want to do this one row at a time and prevent overlap in new rows as well:

insert into t1(amountFrom, amountTo)
    select t2.amountFrom, t2.amountTo
    from (select XX as amountfrom, YY as amountTo
         ) t2
    where not exists (select 1
                      from table1 t1
                      where t1.amountFrom <= t2.amountTo and
                            t1.amountTo >= t2.amountFrom
                     );

This will do the insert one step at a time with the overlap logic.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786