TSQL: Creating a duplicate table and modifying values in the column properly? - sql

I have a master table that I wish to keep as it is. I want to duplicate this table then find a specific record with a where clause and set a column value to null. I then want to reinsert it into the duplicated table without anything getting modified in the master table.
Right now these are the steps that I have taken, however, for some reason the changes propagate all the way to the master table:
select * into Table_Duplicate from Table_Master
create view vw_Filtered as
select Col1, null as Col2 from Table_Master where Col1 = 'Condition'
update
set Table_Duplicate.Col2 = vw_Filtered.Col2
inner join vw_Filtered
on Table_Duplicate.Col1 = vw_Filtered.Col1
Once Statement 3) has been executed, when I do:
select * from Table_Master where Col1 = 'Condition'
I get the modified value in Col2 but I want to get the value before updating it.
Please do let me know if there are any other way to achieve this.

I think you're over-complicating this.
I wont pretend I know why you need to do this in the first place, but if I had to do such a thing I would probably do it like this:
SELECT Col1,
IIF(Col1 = 'Condition', null, Col2) As Col2
[,Coln]
INTO Table_Duplicate
FROM Table_Master
Then you get all the process in a single select into statement.

Related

How do I add Update statement to selected rows I am about to insert into a table with MS SQL query?

I have been busting my head for some time already and without any result.
Honestly I think that I need fresh eyes on this query.
I have written a query that deletes data from one table and puts it into another table. What I can't really figure out, is how to update one column for those rows I am moving, within the same query.
Here is how the query looks:
INSERT table1_archive
SELECT * FROM (
DELETE table
OUTPUT
DELETED.*
WHERE <condition1>
) AS RowsToMove;
What I want is to add also
UPDATE table1 SET <my_column> = "" WHERE <condition1>
Since it is the same condition and table for delete and update, I was thinking that it makes no sense to call two different queries to do some actions for exactly the same rows.
What I want is to clear data out of the <my_column> either before moving rows to table1_archive, or after doing so.
I guess my question is: How would I apply this update statement to the selected rows I am about to insert into the table1_archive?
ANSWER
This question becomes a little redundant as the UPDATE statement was not necessary to achieve what I wanted. I could just list all my columns in the SELECT statement and replace the <my_column> with NULL, or '''.
You can simply manipulate the column to be updated in the select statement.
INSERT INTO table1_archive
SELECT Col1,Col2...,"" AS <my_column> FROM (
DELETE table
OUTPUT
DELETED.*
WHERE <condition1>
) AS RowsToMove;
You can do this in a single statement - but it requires that you enumerate the columns.
Assuming that your tables have columns (col1, col2, col3, mycol), where mycol should be set to null when copied to the archive, you would write this as:
with del as (
delete ...
output deleted.*
where ...
)
insert into table1_archive (col1, col2, col3, mycol)
select col1, col2, col3, null
from del
and also you can try this solution
UPDATE example_table1 table1 ,
(SELECT
my_column1, my_column2
FROM example_table2
WHERE
table1.my_column3=<condition1>
) table2
SET
table1.my_column1 = table2.my_column1,
table1.my_column2 = table2.my_column2
where table1.ID = table2.ID
UPDATE table1 SET
table1.my_column1= table2.my_column1
FROM
example_table1 AS table1
INNER JOIN example_table2 AS table2
ON table1.ID = table2.ID
WHERE
table1.my_column2 = <condition1>

updating sql query value with select statement

I am trying to execute a query which is something like:
update table set column=(select column1 from table1);
I just want to store the value from other table to my column
but when i try my sql query it says
ERROR 1242 (21000): Subquery returns more than 1 row
definitely this means my table1 contains more than 1 row so i want to know that is there any way to store data into column from other table with multiple row.
or basically saving content of other table as a text something like
update table set column='Data in text from other table';
You probably need a correlation clause:
update table
set column = (select column1 from table1 where table.col = table1.col);
You need to decide what column(s) are used for the correlation.
it will work as i am getting your requirement.Please let me know if your requirement is other i ll make changes in query
update table_name t1
inner join table1 t2 on t1.id =t2.id
set column =column1
Your nested query returns multiple rows so you encountered this error.
Try in this way
UPDATE FirstTable
SET FirstTable.ColumnName =tbl2.ColumnName
FROM SecondTable tbl2 WHERE tbl2.Id = FirstTable.Id
There should be a common id or something that will help to find exact row.

How to define destination for an append query Microsoft Access

I'm trying to append two tables in MS Access at the moment. This is my SQL View of my Query at the moment:
INSERT INTO MainTable
SELECT
FROM Table1 INNER JOIN Table2 ON Table1.University = Table2.University;
Where "University" is the only field name that would have similarities between the two tables. When I try and run the query, I get this error:
Query must have at least one destination field.
I assumed that the INSERT INTO MainTable portion of my SQL was defining the destination, but apparently I am wrong. How can I specify my destination?
You must select something from your select statement.
INSERT INTO MainTable
SELECT col1, col2
FROM Table1 INNER JOIN Table2 ON Table1.University = Table2.University;
Besides Luke Ford's answer (which is correct), there's another gotcha to consider:
MS Access (at least Access 2000, where I just tested it) seems to match the columns by name.
In other words, when you execute the query from Luke's answer:
INSERT INTO MainTable
SELECT col1, col2
FROM ...
...MS Access assumes that MainTable has two columns named col1 and col2, and tries to insert col1 from your query into col1 in MainTable, and so on.
If the column names in MainTable are different, you need to specify them in the INSERT clause.
Let's say the columns in MainTable are named foo and bar, then the query needs to look like this:
INSERT INTO MainTable (foo, bar)
SELECT col1, col2
FROM ...
As other users have mentioned, your SELECT statement is empty. If you'd like to select more that just col1, col2, however, that is possible. If you want to select all columns in your two tables that are to be appended, you can use SELECT *, which will select everything in the tables.

Deleting at most one record for each unique tuple combination

I want to delete at most one record for each unique (columnA, columnB)-tuple in my following delete statement:
DELETE FROM tableA
WHERE columnA IN
(
--some subqueryA
)
AND columnB IN
(
--some subqueryB
)
How is this accomplished? Please only consider those statements that work when used against MSS 2000 (i.e., T-SQL 2000 syntax). I can do it with iterating through a temptable but I want to write it using only sets.
Example:
subqueryA returns 1
subqueryB returns 2,3
If the original table contained
(columnA, columnB, columnC)
5,2,5
1,2,34
1,2,45
1,3,86
Then
1,2,34
1,3,86
should be deleted. Each unique (columnA, columnB)-tuple will appear at most twice in tableA and each time I run my SQL statement I want to delete at most one of these unique combinations - never two.
If there is one record for a given unique (columnA, columnB)-tuple,
delete it.
If there are two records for a given unique (columnA,
columnB)-tuple, delete only one of them.
Delete tabA
from TableA tabA
Where tabA.columnC in (
select max(tabAA.columnC) from TableA tabAA
where tabAA.columnA in (1)
and tabAA.columnB in (2,3)
group by tabAA.columnA,tabAA.columnB
)
How often are you going to be running this that it matters whether you use temp tables or not? Maybe you should consider adding constraints to the table so you only have to do this once...
That said, in all honesty, the best way to do this for SQL Server 2000 is probably to use the #temp table as you're already doing. If you were trying to delete all but one of each dupe, then you could do something like:
insert the distinct rows into a separate table
delete all the rows from the old table
move the distinct rows back into the original table
I've also done things like copy the distinct rows into a new table, drop the old table, and rename the new table.
But this doesn't sound like the goal. Can you show the code you're currently using with the #temp table? I'm trying to envision how you're identifying the rows to keep, and maybe seeing your existing code will trigger something.
EDIT - now with better understood requirements, I can propose the following query. Please test it on a copy of the table first!
DELETE a
FROM dbo.TableA AS a
INNER JOIN
(
SELECT columnA, columnB, columnC = MIN(columnC)
FROM dbo.TableA
WHERE columnA IN
(
-- some subqueryA
SELECT 1
)
AND columnB IN
(
-- some subqueryB
SELECT 2 UNION SELECT 3
)
GROUP BY columnA, columnB
) AS x
ON a.columnA = x.columnA
AND a.columnB = x.columnB
AND a.columnC = x.columnC;
Note that this doesn't confirm that there are exactly one or two rows that match the grouping on columnA and columnB. Also note that if you run this twice it will delete the remaining row that still matches the subquery!

Updating a table within a select statement

Is there any way to update a table within the select_expr part of a mysql select query. Here is an example of what I am trying to achieve:
SELECT id, name, (UPDATE tbl2 SET currname = tbl.name WHERE tbl2.id = tbl.id) FROM tbl;
This gives me an error in mysql, but I dont see why this shouldn't be possible as long as I am not changing tbl.
Edit:
I will clarify why I cant use an ordinary construct for this.
Here is the more complex example of the problem which I am working on:
SELECT id, (SELECT #var = col1 FROM tbl2), #var := #var+1,
(UPDATE tbl2 SET col1 = #var) FROM tbl WHERE ...
So I am basically in a situation where I am incrementing a variable during the select statement and want to reflect this change as I am selecting the rows as I am using the value of this variable during the execution. The example given here can probably be implemented with other means, but the real example, which I wont post here due to there being too much unnecessary code, needs this functionality.
If your goal is to update tbl2 every time you query tbl1, then the best way to do that is to create a stored procedure to do it and wrap it in a transaction, possibly changing isolation levels if atomicity is needed.
You can't nest updates in selects.
What results do you want? The results of the select, or of the update.
If you want to update based on the results of a query you can do it like this:
update table1 set value1 = x.value1 from (select value1, id from table2 where value1 = something) as x where id = x.id
START TRANSACTION;
-- Let's get the current value
SELECT value FROM counters WHERE id = 1 FOR UPDATE;
-- Increment the counter
UPDATE counters SET value = value + 1 WHERE id = 1;
COMMIT;