Insert NULL if value matches the value of another column - sql

Lets say I have a table : "MyTable" and I have two columns in it : "val" and "val_new".
Now I want to insert new value into "val_new" but if the values are equal('val' and 'val_new') I want to insert NULL instead.
----------------------
| id | val | val_new |
----------------------
| 1 | 5 | NULL |
----------------------
| 2 | 6 | NULL |
----------------------
Lets have this table for example.
Now :
UPDATE myTable mt
SET mt.val_new = '5'
WHERE mt.id = '1';
I want the value of val_new to remain NULL or be updated to NULL instead of '5'.
EDIT:
I want to UPDATE existing values not INSERTING new rows.

Your question seems a bit confusing in some parts. The way your word it seems like a new row is to be created but it also seems like you want to update it? Hopefully this is what you wanted :)
UPDATE testVal Set val_new = CASE WHEN val = 5 THEN NULL ELSE 5 END
testVal is your table. If you wanted to use a different number just replace both 5 with the number of your choice. I used 5 because you used it in your example.

You need not have to insert a record rather you will have to update the existing one. If you run your insert command a new record will be created. So you table will have
----------------
|val | val_new |
----------------
| 5 | NULL |
----------------
| 6 | NULL |
----------------
| | | <-- if val = val_new
----------------
| | 6 | <==if val<> val_new.
I guess you dont need this output. So the best option is to update the columns.
You can use case statement,
update <yourtable>
set val_new =case
when val_new= val then
NULL
else val_new
end

Related

How should I set a range parameter that can be also a single input in SQL

I try to use
CHECK_NO BETWEEN '&From_Check_No_' AND '&To_Check_No_'
CHECK_NO >= '&From_Check_No_' AND (CHECK_NO <= '&To_Check_No_' OR '&To_Check_No_' IS NULL)
but that can't show the appropriate results when I only input through FromNumber.
Like range input-
From_Check_No_: 3
To_Check_No_: 9
result:
|CHECK_NO |
-----------
| 3 |
| 4 |
| 6 |
| 9 |
Like single input-
From_Check_No_: 3
To_Check_No_: (null)
result:
|CHECK_NO |
-----------
| 3 |
Just pass the same value in the #From_Check_No_ as #To_Check_No_.
DECLARE #From_Check_No_ int = 3;
DECLARE #To_Check_No_ int = 3;
SELECT CHECK_NO
FROM YourTable
WHERE CHECK_NO BETWEEN #From_Check_No_ AND #To_Check_No_;
Note that I say parameters, you should always parameterize your query rather than injecting values into it.

Suggestion for sql scenario

I am having two columns in table
InventoryId | RevisionId
-------------------------
1 | 1
2 | 1
2 | 2
2 | 2
3 | 1
3 | 2
3 | 3
3 | 3
but from now on I want to prevent following records
2 | 2
2 | 2
3 | 3
3 | 3
So I thought to create a unique index on these two columns
but the table having so much existing data. So anything we can do this situation.
Any suggestion?
you can use a trigger to prevent new rows being added with duplicate values
look at this example
create trigger TR_UI_YourTable on YourTable
for update, insert as
begin
set nocount on
if exists (select 1 from inserted i where i.InventoryId = i.RevisionId)
begin
;throw 99001, 'no dupes allowed anymore...', 1
end
end
A better solution would be to move the duplicates to a seperate table for history, and then add a check constraint on these 2 columns
EDIT
you could do it by an check constraint like this
alter table yourtable
add constraint chk_dupes
check ((InventoryId <> RevisionId) or (id <= 12345))
where 12345 is the highest value of the column id now.
You will have to test it a bit if it works on all situations.
Also, it will only work if all new rows have a value in id that is larger then the current highest value (12345 in my example)

Deleting rows from a table when i pass a string

Hello everyone i want to create a procedure that receives a int and a string with the ID's when they are like this:
Int CompeteID = 1
String TeamIDs = "1,8,9"
Meaning there are 3 TeamIDs, TeamID = 1, TeamID = 8 and TeamID = 9.
Here is my DBModel: https://i.gyazo.com/7920cca8000436cfe207353aaa7d172f.png
So what i want to do is to Insert on TeamCompete, the SportID and CompeteID when there are no equal SportID and CompeteID.
Like this:
TeamCompeteID TeamID CompeteID
1 1 1
4 8 1
5 9 1
6 8 1 <---- Can't do this
But i also want to delete from TeamCompete the TeamIDs i dont pass onto the procedure for example:
TeamCompeteID TeamID CompeteID
1 1 1
2 3 1 <---- Delete this
3 4 1 <---- Delete this
But I don't want to delete the TeamCompete's that are on the Event table...
Example:
EventID TeamCompeteID
5 3 <---- Can't delete TeamCompeteID 3
-- even though i didn't past it on TeamIDs
I hope you understanded my explanation.
First and foremost, passing data in this manner is very much a bad idea. You should really try to normalise your data and have one value in each field.
If however, you cannot avoid this, I would recommend you use a string splitting function such as Jeff Moden's if you are on a SQL Server version prior to 2016 (the string_split is built into SQL Server 2016) which returns a table you can join to from a given string and delimiter.
Using Jeff's function above:
select *
from dbo.DelimitedSplit8K('1,8,9',',')
Results in:
+------------+------+
| ItemNumber | Item |
+------------+------+
| 1 | 1 |
| 2 | 8 |
| 3 | 9 |
+------------+------+
So to use with your table:
declare #t table(CompeteID int,TeamID nvarchar(10));
insert into #t values(1,'1,8,9');
select t.CompeteID
,s.Item
from #t t
cross apply dbo.DelimitedSplit8K(t.TeamID,',') s
Results in:
+-----------+------+
| CompeteID | Item |
+-----------+------+
| 1 | 1 |
| 1 | 8 |
| 1 | 9 |
+-----------+------+
You can then use this table in the rest of your update/insert/delete logic.

update a table from another table and add new values

How would I go about updating a table by using another table so it puts in the new data and if it doesnt match on an id it adds the new id and the data with it. My original table i much bigger than the new table that will update it. and the new table has a few ids that aren't in the old table but need to be added.
for example I have:
Table being updated-
+-------------------+
| Original Table |
+-------------------+
| ID | Initials |
|------+------------|
| 1 | ABC |
| 2 | DEF |
| 3 | GHI |
and...
the table I'm pulling data from to update the other table-
+-------------------+
| New Table |
+-------------------+
| ID | Initials |
|------+------------|
| 1 | XZY |
| 2 | QRS |
| 3 | GHI |
| 4 | ABC |
then I want my Original table to get its values that match up to be updated by the new table if they have changed, and add any new ID rows if they aren't in the original table so in this example it would look like the New Table.
+-------------------+
| Original Table |
+-------------------+
| ID | Initials |
|------+------------|
| 1 | XZY |
| 2 | QRS |
| 3 | GHI |
| 4 | ABC |
You can use MERGE statement to put this UPSERT operation in one statement but there are issues with merge statement I would split it into two Statements, UPDATE and INSERT
UPDATE
UPDATE O
SET O.Initials = N.Initials
FROM Original_Table O INNER JOIN New_Table N
ON O.ID = N.ID
INSERT
INSERT INTO Original_Table (ID , Initials)
SELECT ID , Initials
FROM New_Table
WHERE NOT EXISTS ( SELECT 1
FROM Original_Table
WHERE ID = Original_Table.ID)
Important Note
Reason why I suggested to avoid using merge statement read this article Use Caution with SQL Server's MERGE Statement by Aaron Bertrand
You need to use the MERGE statement for this:
MERGE original_table AS Target
USING updated_table as Source
ON original_table.id = updated_table.id
WHEN MATCHED THEN UPDATE SET Target.Initials = Source.Initials
WHEN NOT MATCHED THEN INSERT(id, Initials) VALUES(Source.id, Source.Initials);
You have not specified, what happens in case the valuesin original table are not found in the updated one. But, just in case, you can add this to remove them from original table:
WHEN NOT MATCHED BY SOURCE
THEN DELETE
if you can use loop in PHP and go through all tables and copy one by one to another table.
another option
DECLARE #COUT INT
SET #COUT = SELECT COUNT(*) FROM New_Table
WHILE (true)
BEGIN
IF #COUT = 0
BREAK;
SET #COUT = #COUT - 1
DECLARE #id INT
DECLARE #ini VARCHAR(20)
SET #id = (SELECT id FROM New_Table);
SET #ini = (SELECT Initials FROM New_Table);
IF (SELECT COUNT(*) FROM Original_Table WHERE id=#id ) > 0
UPDATE SET ID = #id,Initials = #ini FROM Original_Table WHERE id = #id;
insert into Original_Table values(#id,#ini);
END
GO

Bulk change all entries for a particular field in SQL database

Let's just say I have a table called TABLE_NAME that looks like this:
id | name | changeme
------------------------
1 | One | 1
2 | Two | 0
3 | Three | 1
4 | Four | 0
5 | Five | 0
Is there an SQL statement I can run on this to change every changeme entry to '0'?
do you mean?
UPDATE TABLE_NAME SET changeme = 0
update TABLE_NAME set changeme = 0 where changeme = 1
update TABLE_NAME SET changeme="0" WHERE id IN (1,3,4)
if you want to update data where ID is specific like 1,3, and 4
This works for single table
UPDATE table_name
SET field_name = replace(same_field_name, 'unwanted_text', 'wanted_text')