Can anyone guide me how to achieve below scenario - plsql

I have source and target tables with some calculation as I mentioned below, I want to populate result set of the calculation from the source table into the destination table.
Columns in destination table are enabled NOT NULL constraint.
Can anyone guide me to achieve below requirement.
SOURCE TABLE:
Source_table1 >>
col1,
col2,
col3
Source_table2 >>
col1,
col2,
col3
TARGET TABLE:
Dest_table:
col1 >> Source_table1.col1+Source_table2.col1
col2 >> Source_table1.col2+Source_table2.col2
col3 >> Dest_table.col1+Dest_table.col2
col4 >> Source_table1.col3+Source_table1.col3+Dest_table.col3
Thanks in advance.

All you need is three layers of summations, something as shown below. A simple Insert into select should work than going for a PL/SQL block. And as per one of your comments, source_tab1.seq_no = source_tab2.seq_no is the join condition between the source tables.
INSERT INTO Dest_table (col1,
col2,
col3,
col4)
SELECT dcol1,
dcol2,
dcol3,
s1col3 + s2col3 + dcol3 dcol4
FROM (SELECT dcol1,
dcol2,
dcol1 + dcol2 dcol3,
s1col3,
s2col3
FROM (SELECT s1col1 + s2col1 dcol1,
s1col2 + s2col2 dcol2,
s1col3,
s2col3
FROM (SELECT s1.col1 s1col1,
s1.col2 s1col2,
s1.col3 s1col3,
s2.col1 s2col1,
s2.col2 s2col2,
s2.col3 s2col3
FROM source_table1 s1
JOIN source_table2 s2
ON s1.seq_no = s2.seq_no)));

Related

check for null values in all columns of a table using SQLite

I have a table with more than 15 columns. 2 of of them are of the type varchar, and most of them of type int and float.
I am new to SQL and am trying to figure out a way by which I can check if any of the columns have a NULL value in it.
Had there been just 4 or 5 columns I could have checked them individually with
SELECT COUNT(*) FROM table_name WHERE col1 IS NULL OR col2 IS NULL OR col3 IS NULL ...
But is there any efficient way to do this on a lot of columns in SQLite specifically?
I have referred to other questions regarding this here but I cannot use xml or store anything. Also I am using SQLite and can only run a query.
There is no way (that I know of) to check all columns if they contain null without explicitly listing all the column names.
Your query is the proper way to do it.
If you want to shorten (not significantly) the code you could use these alternatives:
SELECT COUNT(*) FROM table_name WHERE col1 + col2 + col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE col1 || col2 || col3 IS NULL;
or:
SELECT COUNT(*) FROM table_name WHERE MAX(col1, col2, col3) IS NULL;
The above queries work, for any data type of the columns, because if there is even only 1 column equal to null then addition, concatenation and the scalar function MAX() (and MIN()) all return null.
See the demo.

Eliminate ID if Col2 = (1,2,3)

I am using teradata sql, and I have the following input
If col2 has (1,2,3) values then delete the Id from table, so my desired table is:
I tried all possible ways, but cannot get to eliminate the IDs? Any help or suggestion will help. thanks
DELETE FROM yourTable
WHERE Id IN ( SELECT Id FROM yourTable WHERE col2 IN (1,2,3) )
If you actually want to delete those IDs you better use #MudassirHasan's solution, but if you want to select the other IDs you can utilize Conditional Aggregation in a Group Max:
select *
from mytable
qualify
max(case when col2 (1,2,3) then 1 else 0 end) -- will return zero when those values don't exist
over (partition by id) = 0 -- for an ID

Updating a table with the columns of another

Relatively new to Oracle. I am trying to replace the columns of one table with the columns of another. Here is my code:
update ems.ptnaddress p
set (p.ptnid, p.address1,p.address2, p.address3,p.address4) =
(select p2.ptnid, p2.address1,p2.address2, p2.address3,p2.address4
from tempptnaddress p2
where p.ptnid = p2.ptnid);
I am getting the error :
SQL Error: ORA-01427: single-row subquery returns more than one row
Any ideas of what to do?
Basically your tempptnaddress table has more than one row for at least some of the ptnid values and Oracle isn't going to pick which one of those rows to use to do the update for you. :)
For example, if I have table1 as
COL1 COL2 COL3
1 ONE ENG
1 UNO SPA
2 TWO ENG
3 THREE ENG
4 FOUR ENG
4 CUATRO SPA
and table2 as
COL1 COL2
1
2
3
4
and try and update TABLE2.COL2 using something like:
UPDATE table2 t2
SET col2 = (SELECT col2 FROM table1 t1 WHERE t1.col1 = t2.col1)
what value in column TABLE1.COL2 should it use for 1 and 4? Oracle won't guess for us and that's when you get the ORA-01427.
It might be as easy as just picking one arbitrarily like:
UPDATE table2 t2
SET col2 = (SELECT col2 FROM table1 t1 WHERE t1.col1 = t2.col2 AND ROWNUM = 1)
but you probably want to put in some proper logic there like:
UPDATE table2 t2
SET col2 = (SELECT t1.col2 FROM table1 t1 WHERE t1.col1 = t2.col1 AND t1.col3 = 'ENG')
In your case, you need to get it so that the subquery in your update only returns one row per ptnid.
If you run this:
SELECT ptnid, COUNT(*)
FROM tempptnaddress
GROUP BY ptnid
HAVING COUNT(*) > 1
it will show you what ptnids that have more than one row in tempptnaddress. The trick will be to find out why there is more than one row per ptnid and how to pick the right one to use for the update.
Try this
UPDATE (SELECT p.ptnid ptnid1,p.address1 Addressnew1, p.address2 p.address3 p.address4 Addressnew4,p.ptnid ptnid2, p.address1 Addressold1, p.address2 p.address3 Addressold3, p.address4 Addressold4 FROM ems.ptnaddress p,tempptnaddress p2 WHERE p.ptnid = p2.ptnid) SET ptnid1 = ptnid2,Addressnew1 = Addressold1, Addressnew2 = Addressold2,Addressnew3 = Addressold3,Addressnew4 = Addressold4

how to insert but get data from multiple tables

I have a simple SQL insert query, however two of the data entires come from two other tables,
I know how to get data from from one table in an insert but how do i get data from two tables?
Example (One Table Data)
INSERT INTO TABLE (COL1, COL2, COL3)
SELECT :COL1, :COL2, TABLE2.ID
FROM TABLE2
WHERE TABLE2.NAME = :LEVEL0
The above works fine and pulls relevant data out of table2, issue is i need to add a third table.
INSERT INTO TABLE (COL1, COL2, COL3, COL4)
SELECT :COL1,
:COL2,
(TABLE2.ID FROM TABLE2 WHERE TABLE2.NAME = :LEVEL0),
(TABLE3.ID FROM TABLE3 WHERE TABLE3.NAME = :LEVEL1)
doesn't work i get SQL errors
Subqueries are queries, so they need their own SELECT:
INSERT INTO TABLE (COL1, COL2, COL3, COL4)
SELECT :COL1,
:COL2,
(SELECT ID FROM TABLE2 WHERE NAME = :LEVEL0),
(SELECT ID FROM TABLE3 WHERE NAME = :LEVEL1);
And when all values are computed by subqueries, you do not need to use the SELECT form of the INSERT:
INSERT INTO TABLE (COL1, COL2, COL3, COL4)
VALUES(:COL1,
:COL2,
(SELECT ID FROM TABLE2 WHERE NAME = :LEVEL0),
(SELECT ID FROM TABLE3 WHERE NAME = :LEVEL1));
Literally as i asked the question i found the solution 'cross join'
INSERT INTO TABLE1 (COL1, COL2, COL3, COL4)
SELECT :COL1, :COL2, TABLE2.ID, TABLE3.ID
FROM TABLE2 CROSS JOIN TABLE3
WHERE TABLE2.NAME = :LEVEL0 AND TABLE3.NAME = :LEVEL1

Can I use DECODE in a UPDATE statement?

Can I use DECODE in a UPDATE statement on the left hand side of SET?
UPDATE temp SET DECODE(update_var, 1, col1,
2, col2) = update_value;
This is giving me error as eual sign ignored..
How about this? If the update flag is set to 1, col1 gets updated, if set to 2, then col2 gets updated.
UPDATE temp
SET col1 = DECODE(update_var, 1, update_value, col1),
col2 = DECODE(update_var, 2, update_value, col2)
Also, as a bonus, it'll handle the possible situation where the update variable is set to something other than one or two!
No you can't do that. You can do this in PL/SQL:
IF update_var = 1 THEN
UPDATE temp SET col1 = update_value;
else
UPDATE temp SET col2 = update_value;
END IF;
Or you could use dynamic SQL like this:
l_sql := 'UPDATE temp SET col'||update_var||' = :v';
EXECUTE IMMEDIATE l_sql USING update_value;
You cant use decode in an update statement.
You can however use a merge statement.
http://psoug.org/reference/merge.html
MERGE INTO temp b
USING (
SELECT key, DECODE(update_var, 1, update_value, col1) as col1,
DECODE(update_var, 2, update_value, col2) as col2
FROM temp
WHERE key =theKeyIPassedIn) e
ON (b.key = e.key)
WHEN MATCHED THEN
UPDATE SET b.col1 = e.col1, b.col2 = e.col2
;
Basically you are using the select portion of the merge to decode col1 and col2 to either the update_value or the value that exists already.
This may also be too verbose for your needs, and the solution that uses an if statement or execute immediate may better suit your problem.

Resources