Can I have record as a parameter in INSERT statement? - sql

I'm trying to populate a new table T.
create or replace procedure extractData
is
cursor c1 is
SELECT a.id,a.data,b.id,b.data,c.id,c.data
FROM a LEFT JOIN b ON a.id=b.id
LEFT JOIN c on b.id=c.id;
begin
for currRec in c1
loop
insert into table T
values currRec,(select a_seq.nextval from dual),(select b_seq.nextval from dual),(select b_seq.nextval from dual),SYSDATE
end loop
Will this give me a table with columns from currRec then the sequences and SYSDATE? Also is there a better way to do this without making it more messy than it already is? In the real table, I have about 10 'data' columns in a,b and c each so I'm worried about something screwing up or going out of order. I'm writing a procedure for a data warehouse that takes in data from three different sources and combines them in one table.

INSERT
INTO table
SELECT a.id, a.data, b.id, b.data, c.id, c.data,
a_seq.nextval, b_seq.nextval, c_seq.nextval,
SYSDATE
FROM a
LEFT JOIN
b
ON b.id = a.id
LEFT JOIN
c
ON c.id = b.id

Related

Use a specific column from a result set of a SELECT in another SELECT statement in same SP

I have a SELECT statement which gives me a result set containing ID as a column name. I want to use the ID column in another select. Is there any possible way to do this
SELECT A.Id
,B.Product
,A.Name
,B.ProductCode
FROM Customers A
INNER JOIN Product B ON A.Id = B.Id
I want to use the resulting column A.Id in another Select
SELECT * FROM SELLER WHERE ID = 'A.ID'(How to get this A.ID??)
I need to use this logic inside a Stored Procedure where I have If else condition. So I am not able to use temporary table with same name here.
That's very simple. Just join another source table also to the procedure
SELECT A.Id
,S.*
,B.Product
,A.Name
,B.ProductCode
FROM Customers A
LEFT JOIN Product B ON A.Id = B.Id
LEFT JOIN SELLER S ON S.ID = A.ID

Separated JOIN form main INNER JOINS's

I want to INNER JOIN some tables and then insert a condition where the entries of a table are dependant on another table (that was not joined with the others)
Something like this:
SELECT * FROM TABLE_A AS a
INNER JOIN TABLE_B AS b ON b.id_b=a.id_a
INNER JOIN TABLE_C AS c ON c.id_c=b.id_b
Now I want to add a condition (possibly a "WHERE" clause) that only selects the values in a field in TABLE_C that match another condition, the existence of a value in a field in TABLE_D
Possible statement:
WHERE c.code=d.another_code AND d.reg_number LIKE 999%
How do i declare in the query the TABLE_D, since I do not want to Join it with the others?
In other words, I want to intersect 3 sets (A,B,C) and the other one (set D) is intersected only with set C
The title of the question Run-time error '13': ... doesn't seem to match the content so I'll just answer the SQL part.
Maybe this is what you want?
SELECT * FROM TABLE_A AS a
INNER JOIN TABLE_B AS b ON b.id_b=a.id_a
INNER JOIN TABLE_C AS c ON c.id_c=b.id_b
WHERE c.code = -- or possiby IN instead of =
(SELECT another_code FROM TABLE_D WHERE another_code LIKE '999%')
If the subquery can return multiple rows you need to use WHERE c.code IN instead of WHERE c.code =

Can this be done with a single SQL Join?

I am not sure if this can be done with a single JOIN, but I basically have two tables with an ID column in common. To make it simple I'll say Table A just contains an ID while Table B contains an ID and Code. There is a 1:M relationship between Table A and Table B, however it's also possible an ID from Table A is not contained in Table B at all. I was hoping to have a query return every ID that exists in Table B within a particular code range, or does not exist in Table B at all.
I tried using a LEFT JOIN with something like:
SELECT A.id FROM A LEFT JOIN B ON A.id = B.id AND b.code BETWEEN '000' AND '123'
But, this still gives me the IDs that exist in Table B outside of the code range.
Use a left join, and filter the result to contain the codes in the range, and also the lines where there is no matching record in table B:
select
A.id
from
A
left join B on B.id = A.id
where
B.code between '000' and '123' or B.id is null
What about
SELECT id FROM A LEFT JOIN B ON A.id = B.id
WHERE b.code IS NULL OR b.code BETWEEN ' ' AND '123'

SQL Insert into table A from table B based off table C

I have an empty table that I would like to fill with rows from a second table, based off a third table, Ill call them A,B,C respectively.
Table C has ID numbers that match ID numbers for rows in Table B. For every ID in table C, I want to add the corresponding row from table B into Table A.
This is what I have, and I am getting an error saying that I cannot use the last statement.
INSERT INTO TABLEA
SELECT * FROM TABLEB
WHERE ID FROM TABLEB = ID FROM TABLEC;
DSNT408I SQLCODE = -199, ERROR: ILLEGAL USE OF KEYWORD FROM. TOKEN ( . AT
MICROSECONDS MICROSECOND SECONDS SECOND MINUTES MINUTE WAS EXPECTED
DSNT418I SQLSTATE = 42601 SQLSTATE RETURN CODE
Any help would be appreciated.
INSERT INTO TableA
SELECT B.*
FROM TableB AS B
JOIN TableC AS C ON B.ID = C.ID
Or possibly that will give you too many duplicates (if there are multiple rows in C that match a given row in B), in which case you might need:
INSERT INTO TableA
SELECT B.*
FROM TableB AS B
WHERE B.ID IN (SELECT C.ID FROM TableC AS C)
Or:
INSERT INTO TableA
SELECT DISTINCT B.*
FROM TableB AS B
JOIN TableC AS C ON B.ID = C.ID
Both of those give you one row in A for each row in B that matches one or more rows in C.
How would I add a WHEN clause to this? Let's say Table C has another column called VALUE, and I want to add all the ID numbers that have a value of 'x' or greater. How would I do that, I tried adding JOIN TableC AS C ON B.ID = C.ID AND C.VALUE > 5 but I still got all the values from TABLE C.
Working with the first query (fixing the others being left as an 'exercise for the reader'), then what I think you should be doing is just:
INSERT INTO TableA
SELECT B.*
FROM TableB AS B
JOIN TableC AS C ON B.ID = C.ID
WHERE C.Value > 5
The optimizer should translate that to an equivalent expression:
INSERT INTO TableA
SELECT B.*
FROM TableB AS B
JOIN TableC AS C ON B.ID = C.ID AND C.Value > 5
I'm not clear from your comment whether you somehow added a second reference to TableC in the one query, or you modified your query as shown in this second example. If you were not using LEFT JOIN anywhere, then adding the AND C.Value > 5 term to the ON clause or as a WHERE clause should have yielded the correct data.
When debugging this sort of problem, it is worth noting that this INSERT statement has a perfectly good SELECT statement in it that you can run on its own to review what is going to be added to TableA. You might want to augment the select-list to include (at least) C.ID and C.Value just to make sure nothing is going haywire.

Join and showing different columns from tables

I have a simple SQL question, I thought it would be quite straight forward but have got myself in a muddle. Any help would be appreciated
I have table A which contains a last updated
Table A has a one to many with Table B
Table B has a one to many with Table C
I want to show all rows of table C with the last updated time from table A. I have tried some joins but they dont seem to be quite working. Ideally I want somehting like
select a.lastUpdated c.* from TableA a, TableC c where
a.id in (select a_id from TableB where (select b_id from TableC where c_id = select
id from TableC where XXXX=YYYY))
so I can pass in an id for table C and then get one row returned with the last updated time present.
XXX=YYY would be my criteria for returning one row of table C.
Any help or pointers appreciated
Thanks
Something like
SELECT c.*
FROM TableA AS a
INNER JOIN TableB AS b
ON a.a_id = b.b_id
INNER JOIN TableC AS c
ON b.b_id = c.c_id
WHERE a.lastUpdated = c.lastUpdated;
Should work. This is a situation where a striaght INNER JOIN should suffice; unless of course I have missed something.
I hope this helps.
You should be able to do this by joining A and B together, aggregating the results at the c_id level, and then joining in C:
select tc.*, maxlastupdated
from tablec tc left outer join
(select tb.c_id, max(lastupdated) as maxlastupdated
from tablea ta join
tableb tb
on ta.b_id = tb.b_id
group by ta.id
) ta
on tc.c_id = ta.c_id
You need to drive your SQL query from Table C.
The query below displays the updated timestamp column from table A.
Since it is a one-to-many in the direction of tables A --> B --> C
You will inevitably end-up with a lot of rows in table C - all with the same timestamp.
SELECT c.*, a1.update_timestamp
FROM table_c c, table_b b, table_a a1
WHERE c.join_column = b.join_column
AND b.join_column = a1.join_column
AND a1.update_timestamp =
(SELECT max(a2.update_timestamp) FROM table_a a2
WHERE a2.<identifying columns> = a1.<identifying columns>
);