Informix - where clause with merge into - sql

I am using Informix Dynamic Server Version 12.10.FC9W1X2.
I need to update a table with fields from a different table. I am attempting to use the
MERGE INTO
statement, but I am not able to use a WHERE CLAUSE to filter out information from the table that is being updated as it's causing a syntax error. I also tried adding AND to the WHEN MATCHED and it isn't working.
Is there any way to do this?
This is my statement so far,
MERGE INTO table1 as t1
USING table2 as t2
ON t1.some_no = t2.some
WHEN MATCHED
THEN
UPDATE SET t1.some_other_no = t2.some_other_no, is_processed = 'Y', resolution = 'AAA'

The additional filters on table1 can be placed in the ON clause. For example:
create table t1(col1 int, col2 int, col3 int);
insert into t1 values(1,1,1);
insert into t1 values(1,2,0);
insert into t1 values(1,3,0);
insert into t1 values(2,1,0);
insert into t1 values(3,1,1);
create table t2 (col1 int, col2 int);
insert into t2 values(1,5);
insert into t2 values(2,5);
insert into t2 values(3,5);
merge into t1
using t2
on
t1.col1 = t2.col1
AND t1.col3 = 1
when matched then
update set t1.col2 = t2.col2;
The above results in the following output when selecting from the t1 table
col1 col2 col3
1 5 1
1 2 0
1 3 0
2 1 0
3 5 1

Related

SQL-Sum Values until reach a specific value in another column

I have the following 2 table:
Col1|Col2|Col3
Val1 T1
Val2 T2
Col1|Col2|Col3|Col4
Val1 test 1
Val1 test 2
Val1 T1 3
Val2 test 1
Val2 T2 2
I need to update the values for Col3 of Table 1 with the summation of Col3 of table 2 until Col2 of Table 2 reaches the value from Col2 of Table 1. So, Table 1 should look like this:
Col1|Col2|Col3
Val1 T1 6
Val2 T2 3
So, it adds up 1+2+3 = 6 for T1 and 1+2 = 3 for T2.
Basically, the Col1 for both tables will be the key. I am using MSSQL2008 server. I tried to do this with Cursor but no luck so far.
Please note, the order by column in Table2 is a Date column (Column4). It is ordered by Desc.
You can get this by GROUP BY:
CREATE TABLE #Table1(Col1 VARCHAR(10),Col2 VARCHAR(10),Col3 INT)
CREATE TABLE #Table2(Col1 VARCHAR(10),Col2 VARCHAR(10),Col3 INT,Col4 DATETIME)
INSERT INTO #Table1 VALUES('Val1','T1',0)
INSERT INTO #Table1 VALUES('Val2','T2',0)
INSERT INTO #Table2 VALUES('Val1','test',1,GETDATE())
INSERT INTO #Table2 VALUES('Val1','test',2,GETDATE()-1)
INSERT INTO #Table2 VALUES('Val1','T1',3,GETDATE()-2)
INSERT INTO #Table2 VALUES('Val1','test',4,GETDATE()-3)
INSERT INTO #Table2 VALUES('Val2','test',1,GETDATE())
INSERT INTO #Table2 VALUES('Val2','T2',2,GETDATE()-1)
UPDATE T1
SET T1.Col3 = T2.SummationValue
FROM #Table1 T1
JOIN (
SELECT T2.Col1,T2.Col2,SUM(T2.Col3) OVER(PARTITION BY T2.Col1 ORDER BY Col4 DESC)SummationValue
FROM #Table2 T2
JOIN #Table1 T1 ON T2.Col1 = T1.Col1
)T2
ON T1.Col1 = T2.Col1 AND T1.Col2 = T2.Col2
SELECT * FROM #Table1
DROP TABLE #Table1
DROP TABLE #Table2
OutPut:
Col1 Col2 Col3
Val1 T1 6
Val2 T2 3
SQL Fiddle
This is a bit tricky. You can get the cutoff point using a correlated subquery:
update t1
set col3 = t2.sum_col3
from t1 join
(select t2.col1, sum(t2.col3) as sum_col3
from t2
where t2.t4 >= (select tt2.t4
from t2 tt2 join
t1 tt1
on tt2.col1 = tt1.col1 and
tt2.col2 = tt1.col2
)
group by t2.col1
) t2
on t2.col1 = t1.col1;
Alternatively, you can use window functions (but not a cumulative sum):
update t1
set col3 = t2.sum_col3
from t1 join
(select t2.col1,
sum(t2.col3) as sum_col3
from (select t2.col1,
min(case when tt2.col1 = tt1.col2 then tt2.col4 end) over (partition by tt2.col1) as col4_match
from t2 tt2 join
t1 tt1
on tt2.col1 = tt1.col1
) t2
where col4 >= col4_match
group by t2.col1
) t2
on t2.col1 = t1.col1

ORACLE SQL:More than one WHEN MATCHED condition INSIDE MERGE STATEMENT

I want to use a merge statement in pl/sql and the target table has to be updated on a particular condition. I know we can use multiple when matched condition in sql server with and operator, but i am not sure about Oracle. I am looking for that kind of feature in oracle.
create table table1 (id number, text varchar2(20));
create table table2 (id number, text varchar2(20), text2 varchar2(20));
insert into table1 values (1,'');
insert into table1 values (2,'');
insert into table1 values (3,'');
insert into table2 values (1,'a','b');
insert into table2 values (2,'a','b');
insert into table2 values (3,'a','b');
insert into table2 values (4,'a','b');
I understand you want obtain something like code below with commented line
merge into table1 t1
using table2 t2
on (t1.id = t2.id)
when matched then update set
t1.text = t2.text where t1.id = 1
--t1.text = t2.text2 where t1.id = 2
when not matched then insert values (t2.id, t2.text);
I would do that like:
merge into table1 t1
using (select id, case id when 1 then text when 2 then text2 else null end as tt, text from table2) t2
on (t1.id = t2.id)
when matched then update set
t1.text = t2.tt where t2.tt is not null
--t1.text = t2.text2 where t1.id = 2
when not matched then insert values (t2.id, t2.text);
select * from table1;

How do I extend my query to join the result with another table?

I have two tables. I am making a query on one table, and would like to join the result with a second table to get the final result.
My tables are:
create table table1 (col1 int, col2 int)
create table table2 (col3 int, col4 int)
insert into table1 values
(1, NULL), (2,10), (3, 20)
insert into table2 values
(1,100),(2,200),(3,300)
The query
SELECT col1 FROM table1 WHERE col2 IS NOT NULL
gives me
col1
2
3
How do I extend my query to receive the result as follows:
col1 col4
2 200
3 300
I put this example on SQL Fiddle http://sqlfiddle.com/#!3/9e89e/1 to quickly test queries.
SELECT t1.col1,t2.col4
FROM table1 t1
join table2 t2 on
t1.col1 = t2.col3
WHERE t1.col2 IS NOT NULL
You need to join the tables as per your expected output.
Fiddle

Transfer data from temp table to physical table

I have this table named table1
id uniquefield field1 field2
1 11 test test2
2 12 test2 test3
and I have this value in my temp table #temp1
id uniquefield field1 field2
1 11 test test2
2 12 test2 test3
3 13 test4 test5
4 14 test5 test6
Now, what I want to happen is that I want to transfer all data from #temp1 table. It would insert if data does not exist in table1 table and would update if it exist.
Does anybody know how to do this using SQL Server or dynamic SQL?
Hope to find some response from you.
Temp tables are no different in such cases like you mentioned. The difference is they are only available to the current connection for the user; and they are automatically deleted when the user disconnects from instances. So you can handle these tables like any other SQL table and use a MERGE query to achieve this data manupulation.
Assuming the uniquefield column can be treated as link between these tables.
MERGE table1 t
USING #temp1 t1
ON t.uniquefield = t1.uniquefield
WHEN MATCHED THEN
UPDATE
SET t.id = t1.id,
t.field1 = t1.field1,
t.field2 = t1.field2
WHEN NOT MATCHED BY TARGET THEN
INSERT (id, uniquefield, field1, field2)
VALUES (t1.id, t1.uniquefield, t1.field1, t1.field2 );
You can DROP #temp1 after this and do a SELECT * FROM table1 to check the updated/ inserted data.
Assume 2 table row is identical by id, insert with not exists()
-- Append missing row to table1
INSERT table1
SELECT * FROM #temp1 t WHERE NOT EXISTS(SELECT * FROM table1 WHERE id = t.id)
Temp tables are no different in such cases like you mentioned. The difference is they are only available to the current connection for the user; and they are automatically deleted when the user disconnects from instances. So you can handle these tables like any other SQL table.
Assuming the uniquefield column can be treated as link between these tables.
Update statemant:
update table1
set
t.id = t1.id,
t.field1 = t1.field1,
t.field2 = t1.field2
from table1 t
join #temp1 t1
on t.uniquefield = t1.uniquefield
Insert statement:
insert into table1(id, uniquefield, field1, field2)
select t1.id, t1.uniquefield, t1.field1, t1.field2
from table1 t
join #temp1 t1
on t.uniquefield != t1.uniquefield
This is assuming that id is the table primary key. Otherwise replace appropriately.
UPDATE Table1
SET id= T.id,
Uniquefield = T.Uniquefield,
Field1 = T.field1,
Field2 = T.field2
FROM Table1
INNER JOIN #temp1 T ON T.id = Table1.id;
INSERT INTO Table1 (id, uniquefield, field1, field2)
SELECT id, uniquefield, field1, field2
FROM #temp1
WHERE id NOT IN (SELECT id FROM Table1)
I think the elegant way is to use MERGE here:
SET IDENTITY_INSERT table1 ON;
MERGE INTO table1 AS T
USING #temp1 AS S
ON S.id = T.id
WHEN MATCHED THEN
UPDATE SET
T.uniquefield = S.uniquefield,
T.field1 = S.field1,
T.field2 = S.field2
WHEN NOT MATCHED BY TARGET THEN
INSERT (id, uniquefield, field1, field2)
VALUES (S.id, S.uniquefield, S.field1, S.field2);
SET IDENTITY_INSERT table1 OFF;
I have added the IDENTITY_INSERT there just in case ID column in your table1 is an IDENTITY and you might want to keep the one from #temp1 table. If you dont need / have IDENTITY, just remove those lines.
you can simply use this query:-
insert into table1
select * from (
select #temp.workersID,#temp.W_name,#temp.salary,#temp.joining_year,#temp.city,#temp.id
from #temp
full join workers
on #temp.WorkersID = workers.WorkersID
where workers.WorkersID is null
) ds

Oracle - Missing Right Parenthesis

The table structure is as follows:
NOTE: The names used are for illustrative purposes only.
Table T1 - col1 INT, col2 CHAR, col3 VARCHAR
Table T2 - col1 INT, col2 VARCHAR col3 CHAR
Table T3 - col1 INT - col1 from Table 2 col2 INT - col2 from Table T col3 INT
SELECT tt1.col2, COUNT(tt1.col1) FROM T1 tt1, T2 tt2, T3 tt3 WHERE tt2.col1 = tt3.col1 AND
tt3.col2 = tt1.col1 GROUP BY tt1.col1, tt1.col2 HAVING EVERY (tt2.col3 = 'something');
This shows an error that matches the title of the question; However, no error is reported if I remove the HAVING clause.
Is the query syntactically correct?
SELECT tt1.col2, COUNT(tt1.col1)
FROM T1 tt1
JOIN T3 tt3 ON (tt3.col2 = tt1.col1)
JOIN T2 tt2 ON (tt2.col1 = tt3.col1)
WHERE tt2.col3 = 'something'
GROUP BY tt1.col2;
It doesn't appear that you need a HAVING clause. You use a HAVING clause when you need to filter results after your GROUP BY has been executed. For example, if you wanted only the records with a count(tt1.col1) greater than 10, you would use a HAVING clause. (HAVING count(tt1.col1) > 10)