Some kind of IF condition in INSERT - sql

I have next tables:
table1 table2
id. value position id state
1. false
What I need is to insert data in to table1 if state from table2 is true.
Something like:
INSERT INTO table1(value, position)
VALUES('someVal', 3)
IF table2.id = 1 AND table2.state = true

Do you want exists?
INSERT INTO table1(value, position)
SELECT v.value, v.position
FROM (VALUES('someVal', 3)) v(value, position)
WHERE EXISTS (SELECT 1 FROM TABLE2 t2 WHERE t2.id = 1 AND t2.state = true);

You can select only item where table2.State = true before inserting
If you have your data comming from another table it would look like this
INSERT INTO table1(value, position)
SELECT ValueId, Value
FROM TableValue
INNER JOIN Table2
ON TableValue.ValueID = Table2.ID
WHERE table2.state = true

Related

Update row in a table based on multiple rows in another table

I have two tables: table1 and table2:
table1 has columns id and integer
table2 has columns id and boolean
table2 can have multiple rows with the same id
I want to update the integer column of table1 by looking at all rows with the same id in table2 and seeing if any of the boolean values are true. If so I want table1.integer to be 1, else I want it to be 0.
I have tried something like this:
UPDATE table1,
(
SELECT table2.id, Sum(table2.boolean) > 0
) AS 'condition'
from table2
WHERE 1
GROUP BY table2.id) table3
SET table1.integer =IF(table3.condition, 1, 0) where table1.id = table3.id
And it seems to work, but I wanted to ask if there is a nicer/cleaner/more succinct way of updating the rows of table1 according to multiple rows of table2.
I would recommend EXISTS:
UPDATE table1 t1
SET t1.integer = (EXISTS (SELECT 1
FROM table2 t2
WHERE t2.id = t.id AND
t2.boolean
)
);
This can take advantage of an index on table2(id, boolean). With such an index, it should be faster than an approach that uses JOIN and AGGREGATION.
The syntax of your query is MySql like, so you can do a join like this:
UPDATE table1 t1 INNER JOIN (
SELECT id, MAX(boolean) maxboolean
FROM table2
GROUP BY id
) t2 ON t2.id = t1.id
SET t1.integer = t2.maxboolean
If there are ids in table1 without a corresponding id in table2 and you want the integer column for them to be updated to 0 then use a LEFT join:
UPDATE table1 t1 LEFT JOIN (
SELECT id, MAX(boolean) maxboolean
FROM table2
GROUP BY id
) t2 ON t2.id = t1.id
SET t1.integer = COALESCE(t2.maxboolean, 0)

How to Update column values of T1 from T2 using one condition?

I tried this query and i get this msg SQL Error: ORA-00933: SQL command not properly ended ,but i can't see where the problem realy is ?
update T1 set T1.name=T2.name from Table1 T1
inner join Table2 T2
on T1.id=T2.id where T2.id in (select id from Table2 group by id having count(entity)=1);
Your statement is not valid Oracle syntax.
You have two common options.
Option #1: use a correlated subquery in your UPDATE...
update table t1
set t1.name = ( SELECT t2.name
FROM table2 t2
WHERE t2.id = t1.id
AND t2.id IN ( SELECT t2a.id
FROM table2 t2a
GROUP BY t2a.id
HAVING COUNT(t2a.entity) = 1 )
)
where exists ( SELECT 'x'
FROM table2 t2
WHERE t2.id = t1.id
AND t2.id IN ( SELECT t2a.id
FROM table2 t2a
GROUP BY t2a.id
HAVING COUNT(t2a.entity) = 1 )
;
Option #2: (my preference) use a MERGE statement:
merge into table1 t
using ( SELECT t2.id,
t2.name,
COUNT(t2.entity) OVER ( PARTITION BY t2.id ) entity_count
FROM table2 t2
) u
ON ( t.id = u.id AND u.entity_count = 1 )
WHEN MATCHED THEN UPDATE SET t.name = u.name;
I usually test SQL before I post it, but no time today. So, there might be syntax errors in the above.
I would phrase the update as:
update table t1
set t1.name = (select t2.name
from table2 t2
where t2.id = t1.id and rownum = 1
)
where (select count(t2.entity)
from table2 t2
where t2.id = t1.id
) = 1;
I'm not sure if I understood the data context. I created an example where ID's aren't UNIQUE
create table T1 ( name varchar2(55), id number(4,0), entity number(2,0));
create table T2 ( name varchar2(55), id number(4,0), entity number(2,0));
insert into T1 (name, id, entity) values ('T1name1', 1, 1);
insert into T1 (name, id, entity) values ('T1name2', 2, 1);
insert into T1 (name, id, entity) values ('T1name3', 3, 3);
insert into T1 (name, id, entity) values ('T1name4', 4, 4);
insert into T2 (name, id, entity) values ('T2name1', 1, 1);
insert into T2 (name, id, entity) values ('T2name2', 2, 1);
insert into T2 (name, id, entity) values ('T2name3', 3, 3);
insert into T2 (name, id, entity) values ('T2name4', 3, 1);
update T1 set name =
nvl(
( select name
from T2
where T2.id = T1.id
and exists
( select 'x'
from T2 table2
where table2.id = T2.id
group by id
having count(entity) = 1)
)
,T1.name)
In this context, just T1.id = 1 and T1.id = 2 will be updated (T2.id = 3 has count(entity) = 2)

SQL Statement with a simple join

I have problems to do a SQL statement. I have the following example-tables:
Table 1:
ID - | - Name
1; ABC
2; DEF
3; GHI
Table 2:
ID - | - Bool
1; true
1; false
2; true
3; false
3; false
I want to join the tables but show only the entities, which have NO false in table 2. Example:
Is there a false and a true in one entity, I don't want to have the Entity in my Result. Are there true true in one entity, it is ok.
My Problem are Entitys, which have true and false in table 2...
Thank you for helping!
Since your IDs have duplicates in table2, you'll have to do some inventory/counting:
SELECT table1.ID, table1.Name,
SUM(table2.Bool = false) as trues,
SUM(table1.Bool = true) as falses
FROM table1
INNER JOIN table2 ON table1.ID = table2.ID
GROUP BY table1.ID
HAVING falses = 0
This will give you all records that have a TRUE record in Table 2 but no FALSE record:
SELECT ID, Name
FROM Table1 t1
WHERE EXISTS
(
SELECT NULL
FROM Table2 t2
WHERE t2.ID = t1.ID
AND t2.Bool = 'true'
)
AND NOT EXISTS
(
SELECT NULL
FROM Table2 t2
WHERE t2.ID = t1.ID
AND t2.Bool = 'false'
)
I do not have a DB handy, but I wonder if this would work:
select t1.id, t1.name
from table1 t1
inner join table2 t2 on t1.id = t2.id
where t1.id not in (select id from table2 where Bool = 'false')
If the column 'bool' on table 2 is truly the boolean data type, which is 1 if true, and 0 if false, then any ID having a minimum bool value not equal to 0 must have no false values.
So you could run: (see fiddle: http://sqlfiddle.com/#!2/76639/1/0)
select t1.id, t1.name
from table_1 t1
join (select id from table_2 group by id having min(bool) <> 0) v
on t1.id = v.id

How to modify SQL INSERT query to fail if nested SELECT returns NULL

I have a set of SQL queries that each is an insert statement that gets its values from other tables:
insert into table1 values (
(select tableID from Table1 where Name = 'Name1'),
(select tableID from Table2 where Name = 'Name2'),
(select tableID from Table3 where Name = 'Name3')
)
If the select statements can't find the value in the table (ie, if there is no 'Name1' in Table1), then that field becomes NULL.
Aside from changing the table design to not allow NULL's, is there a way I can modify my SQL to fail rather than insert NULL, if the nested select statements can't find the specified value?
What I would do is store the values in variables initially:
DECLARE #tableID1 INT = (SELECT tableID FROM Table1 WHERE Name = 'Name1')
Then you can do an
IF #tableID1 IS NOT NULL AND #tableID2 IS NOT NULL...
INSERT...
or alternatively an INSERT INTO table1 SELECT #tableID1 WHERE #tableID1 IS NOT NULL.
If for some reason you wanted to do it in a single messy statement you could do:
INSERT INTO table1
(select tableID from Table1 where Name = 'Name1'),
(select tableID from Table2 where Name = 'Name2'),
(select tableID from Table3 where Name = 'Name3')
WHERE EXISTS (select 1 from Table1 where Name = 'Name1'),
AND EXISTS (select 1 from Table2 where Name = 'Name2'),
AND EXISTS (select 1 from Table3 where Name = 'Name3')
A bit long winded, but this work and it should be pretty quick.
IF OBJECT_ID('tempdb..##table1') IS NOT NULL
DROP TABLE ##table1
insert into ##table1 values (
(select tableID from Table1 where Name = 'Name1'),
(select tableID from Table2 where Name = 'Name2'),
(select tableID from Table3 where Name = 'Name3')
)
insert into table1
SELECT * FROM ##table1
where tableID is not null
You could also just insert it and then,
DELETE FROM table1 where tableID is null
Use update statement
try doing
Update Table table_name set id = (select if(Name = NULL, NULL, tableID) from Table1 where Name = 'Name1')
The construct you are looking for is insert . . . select. This allows you to put a where clause on the query. Because your subqueries have to return one row, you can do a cross join, which will return at most one row:
insert into table1(id1, id2, id3)
select t1.tableID, t2.tableId, t3.tableId
from (select tableID from Table1 where Name = 'Name1') t1 cross join
(select tableID from Table2 where Name = 'Name2') t2 cross join
(select tableID from Table3 where Name = 'Name3') t3
where t1.tableID is not null and t2.tableId is not null and t3.tableId is not null;
My guess is that the where clause is unnecessary. NULL in your case is probably not the value of the table id, but represents that no row was found. A cross join on a table with no rows returns no rows, so nothing will be inserted.
Please try with in built sql function to check if inner query is returning null. For example
insert into table1 values (
IFNULL((select tableID from Table1 where Name = 'Name1'),""),
IFNULL((select tableID from Table2 where Name = 'Name2'),"")
)

Multiple SELECT with NOT IN - inner Select statement returns empty and the whole SELECT returns empty

There are two table TABLE1 and TABLE2 in which there is a common field ID. I wanted to retrieve values from TABLE2 that doesnot match in TABLE1 based on ID value.
select * from TABLE2 where subject = 1 and ID NOT IN (select ID from TABLE1 where subject = 1)
Sample:
TABLE1 ID SUBJECT 1 1
TABLE2 ID SUBJECT 1 1 2 1
The expected result is 2 and it works fine.
But when TABLE1 is empty or the inner select ID from TABLE1 where subject = 1 returns empty, the whole select statement returns empty.
But the expected result is 1, 2
Is there any way to achieve this ?
Use a left join
select t2.*
from table2 t2
left outer join table1 t1 on t1.id = t2.id and t1.subject = 1
where t2.subject = 1
and t1.id is null
See a good explanation of joins
I think you can use not exists also for this work -
select * from TABLE2 where subject = 1 and NOT exists
(select 1 from TABLE1 where subject = 1 and table1.id = table2.id)