I want to compare two tables recordby record. I have two cursor for each table. The code looks like this
Declare Cursor c1 for SELECT * from Table1
OPEN c1
While ##Fetch_status=0
Begin
Declare Cursor c2 for SELECT * from Table2
OPEN c2
WHILE ##Fetch_Status=0
Begin
/*Comparison happens here*/
END
END
When fecthing, must I specify which cursor I am fetching and how do I do that?
EDIT
For each record in Table1 I want to
Search Table2 for that record based on the primary key.
When it is found, I want to update the extra column values in Table2 based on the value of a column in table1.
When this record is missing in table2, I want to copy it
from table1 to table2 and set a default value of the extra column in
table2.
Open to other solutions (not restricted to cursors)
If tables have same column definition, the fastes way is just use 'except' clause:
SELECT * from Table1
except
SELECT * from Table2
also run it in opposite way:
SELECT * from Table2
except
SELECT * from Table1
You'll see the exact set difference:
EXCEPT and INTERSECT
Redgate has a great tool for this, if you'd rather just spend a few dollars:
You can get a free trial to see if it suits your needs.
Can't you just...
SELECT * FROM Table1 LEFT JOIN Table2 ON <your matching criteria>
...and then perform INSERT for the rows whose right "half" is NULL and UPDATE for those whose isn't?
Related
I have been trying to copy the data listed in one table to another that are both located in the same database. However, every time I have everything entered, it runs the query and says 0 rows updated.
I have tried several variations in an attempt to get this to work. One such attempt is as listed below. I found this while researching in an attempt to get this done.
UPDATE
t1
SET
t1.column = t2.column
FROM
Table1 t1
INNER JOIN Table2 t2
ON t1.id = t2.id;
Any help on this would be greatly appreciated.
UPDATE will only modify records that already exist, if you want to insert rows that exist on another table use INSERT.
You can combine INSERT and SELECT to copy a whole table1 into a table2.
INSERT INTO table2 SELECT * FROM table1;
You can use INSERT IGNORE to copy only records that don't exist yet (based on unique keys).
You can also specify fields to copy in case the tables are different:
INSERT INTO table2 (id, first_name, last_name) SELECT id, name, surname FROM table1;
I have two tables in my SQLite Database (dummy names):
Table 1: FileID F_Property1 F_Property2 ...
Table 2: PointID ForeignKey(fileid) P_Property1 P_Property2 ...
The entries in Table2 all have a foreign key column that references an entry in Table1.
I now would like to select entries from Table2 where for example F_Property1 of the referenced file in Table1 has a specific value.
I tried something naive:
select * from Table2 where fileid=(select FileID from Table1 where F_Property1 > 1)
Now this actually works..kind of. It selects a correct file id from Table1 and returns entries from Table2 with this ID. But it only uses the first returned ID. What I need it to do is basically connect the returned IDs from the inner select by OR so it returns data for all the IDs.
How can I do this? I think it is some kind of cross-table-query like what is asked here What is the proper syntax for a cross-table SQL query? but these answers contain no explaination of what they are actually doing so I'm struggeling with any implementation.
They are using JOIN statements, but wouldn't this mix entries from Table1 and Table2 together while only checking matching IDs in both tables? At least that is how I understand this http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
As you may have noticed from the style, I'm very new to using databases in general, so please forgive me if not everything is clear about what I want. Please leave a comment and I will try to improve the question if neccessary.
The = operator compares a single value against another, so it is assumed that the subquery returns only a single row.
To check whether a (column) value is in a set of values, use IN:
SELECT *
FROM Table2
WHERE fileid IN (SELECT FileID
FROM Table1
WHERE F_Property1 > 1)
The way joins work is not by "mixing" the data, but sort of combining them based on the key.
In your case (I am assuming the key field in Table 1 is unique), if you join those two tables on the primary key field, you will end up with all the entries in table2 plus all corresponding fields from table1. If you were doing this:
select * from table1, table2 where table1.fieldID=table2.foreignkey;
then, providing your key fields are set up right, you will end up with the following:
PointID ForeignKey(fileid) P_Property1 P_Property2 FileID F_Property1 F_Property2
The field values from table1 would be from matching rows.
Now, if you do this:
select table1.* from table 1, table2 where
table1.fieldID=table2.foreignkey and F_Property1>1;
Would essentially get the same set of records, but will only show the columns from the second table, and only those that satisfy the where condition for the first one.
Hope this helps :)
If I understood your question correctly this will get the job done.
Select t2.*
from table1 t1
inner join table2 t2 on t2.id = t1.id
where t1.Prop = 'SomeValue'
I am trying to make an MS SQL database, and I am quite new to this.
Lets say I have tables with columns
Table1=[Client_ID, Client_Name]
Table2=[Product, Client_ID]. (Client_ID is a FK to Table1)
Now I want to update data in Table 2 and I already have some info in Table 1. Is there a way to insert into T2 if I only know Product and Client_Name? (Somehow lookup client_ID in first table based on his name) What if I dont have that specific client in Table1 yet, can he be inserted during the insertion in T2?
Also I need to grab the data from T2, but I would want to see a table that is [Product, Client_Name]. Is that kind of lookup/replace possible in SQL?
I know I could try to solve these problems beforehand - I'm using Excel as a frontend for accessing my DB, but I hope there is an easier way to do this with SQL itself.
You can insert into Table 2 as follows
'You are passing #Product, #Client_Name
'First look for whether client name is present in table1
declare #clientId as integer;
select #clientId =Client_ID from Table1 where Client_Name=#Client_Name
if #clientId >0 'When there is client name in Table1
begin
insert into table2
values(#Product, #clientId)
end
else 'There is no client name, so we have to insert client name first then gets its id
begin
insert into table1
values(#Client_Name)
'Get id of newly added client, you can done this many way, but here is the simplest way like previous
select #clientId=Client_ID from Table1 where Client_Name=#Client_Name
'Now insert into table2
insert into table2
values(#Product, #clientId)
end
You can get the data the way you wanted by using Join
Select Table2.Product, Table1.Client_Name from table1 inner join table2 on table1.Client_ID = table2.Client_ID
I want to compare two tables recordby record. I have two cursor for each table. The code looks like this
Declare Cursor c1 for SELECT * from Table1
OPEN c1
While ##Fetch_status=0
Begin
Declare Cursor c2 for SELECT * from Table2
OPEN c2
WHILE ##Fetch_Status=0
Begin
/*Comparison happens here*/
END
END
When fecthing, must I specify which cursor I am fetching and how do I do that?
EDIT
For each record in Table1 I want to
Search Table2 for that record based on the primary key.
When it is found, I want to update the extra column values in Table2 based on the value of a column in table1.
When this record is missing in table2, I want to copy it
from table1 to table2 and set a default value of the extra column in
table2.
Open to other solutions (not restricted to cursors)
If tables have same column definition, the fastes way is just use 'except' clause:
SELECT * from Table1
except
SELECT * from Table2
also run it in opposite way:
SELECT * from Table2
except
SELECT * from Table1
You'll see the exact set difference:
EXCEPT and INTERSECT
Redgate has a great tool for this, if you'd rather just spend a few dollars:
You can get a free trial to see if it suits your needs.
Can't you just...
SELECT * FROM Table1 LEFT JOIN Table2 ON <your matching criteria>
...and then perform INSERT for the rows whose right "half" is NULL and UPDATE for those whose isn't?
I use a cursor to iterate through quite a big table. For each row I check if value from one column exists in other.
If the value exists, I would like to increase value column in that other table.
If not, I would like to insert there new row with value set to 1.
I check "if exists" by:
IF (SELECT COUNT(*) FROM otherTabe WHERE... > 1)
BEGIN
...
END
ELSE
BEGIN
...
END
I don't know how to get that row which was found and update value. I don't want to make another select.
How can I do this efficiently?
I assume that the method of checking described above isn't good for this case.
Depending on the size of your data and the actual condition, you have two basic approaches:
1) use MERGE
MERGE TOP (...) INTO table1
USING table2 ON table1.column = table2.column
WHEN MATCHED
THEN UPDATE SET table1.counter += 1
WHEN NOT MATCHED SOURCE
THEN INSERT (...) VALUES (...);
the TOP is needed because when you're doing a huge update like this (you mention the table is 'big', big is relative, but lets assume truly big, +100MM rows) you have to batch the updates, otherwise you'll overwhelm the transaction log with one single gigantic transaction.
2) use a cursor, as you are trying. Your original question can be easily solved, simply always update and then check the count of rows updated:
UPDATE table
SET column += 1
WHERE ...;
IF ##ROW_COUNT = 0
BEGIN
-- no match, insert new value
INSERT INTO (...) VALUES (...);
END
Note that this approach is dangerous though because of race conditions: there is nothing to prevent another thread from inserting the value concurrently, so you may end up with either duplicates or a constraint violation error (preferably the latter...).
This is just psuedo code because I have no idea of your table structure but I think you will understand... basically Update the columns you want then Insert the columns you need. A Cursor operation sounds unnecessary.
Update OtherTable
Set ColumnToIncrease = ColumnToIncrease + 1
FROM CurrentTable Where ColumnToCheckValue is not null
Insert Into OtherTable (ColumnToIncrease, Field1, Field2,...)
SELECT
1,
?
?
FROM CurrentTable Where ColumnToCheckValue is not null
Without a sample, I think this is the best I can do. Bottom line: you don't need a cursor. UPDATE where a match exists (INNER JOIN) and INSERT where one does not.
UPDATE otherTable
SET IncrementingColumn = IncrementingColumn + 1
FROM thisTable INNER JOIN otherTable ON thisTable.ID = otherTable.ID
INSERT INTO otherTable
(
ID
, IncrementingColumn
)
SELECT ID, 1
FROM thisTable
WHERE NOT EXISTS (SELECT *
FROM otherTable
WHERE thisTable.ID = otherTable.ID)
I think you'd be better off using a view for this -- then it's always up to date, no risk of mistakenly double/triple/etc counting:
CREATE VIEW vw_value_count AS
SELECT st.value,
COUNT(*) AS numValue
FROM SOME_TABLE st
GROUP BY st.value
But if you still want to use the INSERT/UPDATE approach:
IF EXISTS(SELECT NULL
FROM SOMETABLE WHERE ... > 1)
BEGIN
UPDATE TABLE
SET count = count + 1
WHERE value = #value
END
ELSE
BEGIN
INSERT INTO TABLE
(value, count)
VALUES
(#value, 1)
END
What about Update statement with inner join to perform +1, and Insert selected rows that do not exist in the first table.
Provide the tables schema and the columns you want to check and update so I can help.
Regards.