I want to create a trigger which will prevent update in a row from that table if that entry is present in another table too.
example
Table M
m_id title
1 abc
2 def
3 ghi
Table N
n_id m_id
1 2
2 3
so if try to update values 2 or 3 in table m it shouldn't allow that
whereas if i try to update value 1 from table it should do so.
You'll have to create a trigger BEFORE UPDATE ON m FOR EACH ROW that checks IF OLD.m_id <> NEW.m_id AND EXISTS (SELECT 1 FROM n WHERE n.m_id = OLD.m_id) and throws an exception in that case.
Related
I have a Circus table as follow
circus_id
circus_date
circus_show_price
1
09-12-2020
78
2
12-01-2021
82
and a Ticket table as follow
ticket_id
circus_id
ticket_category
1
1
Adult
2
1
Student
3
1
Children
4
2
Adult
5
2
Children
6
2
Adult
and i want to alter the circus table by adding a new column called ticket_sold and the value should be as follow
circus_id
circus_date
circus_show_price
ticket_sold
1
09-12-2020
78
3
2
12-01-2021
82
3
this is what I have tried
alter table circus add ticket_sold numeric(3) default 0;
update circus set ticket_sold = (select count(ticket_id) from ticket group by circus_id);
it gives me an error said
single-row subquery returns more than one row
In-general, don't, as you will end up with a ticket_sold column that rapidly becomes out-of-sync with the ticket table.
If you want to have a dynamically updating column then:
1. Use a view.
You can just compute the value whenever you need it:
CREATE VIEW circus_view (circus_id, circus_date, circus_show_price, tickets_sold) AS
SELECT c.circus_id,
c.circus_date,
c.circus_show_price,
(SELECT COUNT(*) FROM ticket t WHERE t.circus_id = c.circus_id)
FROM circus c;
2. Use a trigger.
If you must persist the number of tickets in the circus table then:
ALTER TABLE Circus ADD tickets_sold NUMBER;
CREATE TRIGGER circus_tickets
AFTER INSERT OR UPDATE OR DELETE ON Ticket
BEGIN
UPDATE Circus c
SET tickets_sold = (SELECT COUNT(*) FROM ticket t WHERE t.circus_id = c.circus_id);
END;
/
fiddle
Is is not group by clause you need because query then returns number of tickets per each circus, but - then you get as many rows as there are circus_ids in the ticket table. Instead, correlate subquery to the main table:
update circus c set
c.ticket_sold = (select count(t.ticket_id)
from ticket t
where t.circus_id = c.circus_id
);
I have a table where records are inserted and updated. In case of updates, a new row is inserted into the table. In order to track updates for a given record, there's a column added to the table called root_record_id which holds the id of the very first record in the update chain.
For eg: Consider the record table schema as follows:
id
root_record_id
other columns
1
1
...
2
2
...
3
1
...
4
1
...
5
2
...
In this case, a record with id=1 was inserted, which was then updated to id=3 and then to id=4. Similarly the record with id=2 was inserted and then updated to id=5.
I want to add a version column to this table, where version is incremented on each update and starts with 0.
id
root_record_id
version
other columns
1
1
0
...
2
2
0
...
3
1
1
...
4
1
2
...
5
2
1
...
I tried writing queries using group by clause on root_record_id but failed to accomplish the task.
If you are looking for the general sequence on how to add the column and then pre-fill the values, then follow this fiddle: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=5a04b49fbda3883a9605f5482e252a1b
Add the version column allowing nulls:
ALTER TABLE Records ADD version int null;
Update the version according to your logic:
UPDATE Records
SET version = lkp.version
FROM Records r
INNER JOIN (
SELECT Id, COUNT(root_record_id) OVER (partition by root_record_id ORDER BY id ASC)-1 as version
FROM Records
) lkp ON r.Id = lkp.Id;
Alter the version column to NOT allow nulls
ALTER TABLE Records ALTER COLUMN version int not null;
Finally, ensure that you increment the version column during new row inserts.
DBFIDDLE
This query produces the version that you can use (in an update, or in a trigger):
SELECT
id,
root_record_id,
RANK() OVER (partition by root_record_id ORDER BY id ASC)-1 version
FROM table1
ORDER BY id;
output:
id
root_record_id
version
1
1
0
2
2
0
3
1
1
4
1
2
5
2
1
Table A
Id name phone
1 sam 7753457893
2 tom 7753457893
3 pop 7753457893
4 john 7753457893
table B
name phone
sam 7753457893
tom 7753457893
pop 7753457893
john 7753457893
How to find if all the columns in table A are present in table B or not. I tried using except but I am getting a compilation error "invalid no of columns for set operator input branches, expected 22, got 11 ".I used this query
"select * from table B
except
select * from table A".
Table A has 22 columns and table B has 11 columns. I need a query to know that all the columns in table B are in table A
Basically I want to know table B is a subset of table A or not.
You can use this query
SELECT ColumnFromB
FROM TableB
EXCEPT
SELECT ColumnFromA
FROM TableA
This will give you a list of records that are in B but not in A.
Then you can insert the result into a table variable, and check its COUNT
(if count= 0 'subset'
else is not subset).
This question already has answers here:
SQL update query using joins
(13 answers)
Closed 4 years ago.
I need to update a column in a table X with values that are written in another table Y. Mind you that there are gaps in the Id column as several/some rows were deleted. It starts with 63450 the Id column in table X, and it is not really sequential as shown below:
table X
Id Name Value
-------------------------------------------
63450 cmd NULL
63451 Jong NULL
63456 Xau-Min NULL
63457 bgf NULL
63458 tcr NULL
63459 cro NULL
63500 344453f NULL
63501 stackoverflow NULL
Table Y (parametrization)
Id Acronym Code
-------------------------------
1 cmd 545654
2 bgf 454565
3 cro 555555
4 rtg 465456
5 ert 546546
6 tcr 878787
Now after updating table X it should appear the following. It will update the vALUE in table X according to the matches in table Y...
table X after updating....
Id Name Value
-------------------------------------------
63450 cmd 545654
63451 Jong NULL
63456 Xau-Min NULL
63457 bgf 454565
63458 tcr 878787
63459 cro 555555
63500 344453f NULL
63501 stackoverflow NULL
if I try with
USE Database
DECLARE #counter int
SET #counter=(select count(*) from table_X)
WHILE #counter>0
BEGIN
UPDATE table_X
SET Value=(select Code
from table_Y b inner join table_X a on a.Name=b.Acronym
where a.Id= max(a.Id)-#counter+1)
SET #value=#value-1
END
it WILL not work as the Id is not sequential... how to achieve the updated table X as shown?
2nd: it would be nice to have a function to detect only letters (in the column Name of table X).. is there any in SQL? I only know to detect numeric values in strings: the isnumeric() function.
Thanks. :)
I think this is what you're after:
UPDATE X
SET [Value] = Y.Code
FROM TableX X
JOIN TableY Y ON X.[name] = Y.Acronym;
There's definitely no need for a loop here. In fact, using a looping structure in SQL is generally the worst thing to do for performance.
This is actually quite a simple query, in terms of SQL statements, so do you understand what it's doing?
the primary key ID values in this table are being used in our 2 systems that were recently merged, however there is a large number of items in one of the systems that are pointing to the wrong id values, i need to update the ID(PK) values so that the 6 million existing items will be pointing to the correct row.
id like to update the id columns to the following:
ID
1 to 5
2 to 6
3 to 7
4 to 1
5 to 2
6 to 3
7 to 4
Well, assuming it is not an IDENTITY column (in which case you'll need to set IDENTITY_INSERT to on) then the following should work (see SQLFiddle for example)
UPDATE MyTable
SET ID =
CASE WHEN ID >= 4 SET ID - 3
ELSE ID + 4
END
Use update query with a case statement
Update tableName set PkId = Case PkId
When 1 then 5
When 2 then 6
When 3 then 7
When 4 then 1
When 5 then 2
When 6 then 3
When 7 then 4 End
Where PkId In (1,2,3,4,5,6,7)
If the values in your answer aer just a small subset of the values that need to be change (Do all 6 million need to change?), then you need to Create a mapping table that has the old incorrect value and the new correct value, and use that (with a join) instead of the case statement.
Update t set PkId = map.NewPkId
From tablename t
Join mappingTable m
On m.oldPkId = t.PkId