i have 2 cursor in which cursor 1 has select * from table 1 and cursor 2 has select * from table 2. I need to compare 2 cursors and if the fetched row in the cursor 1 is not equal to fetched row of cursor 2, then i wants to delete that fetched row from table 2. Please help me how to do this?
You can use EXCEPT to identify the changed rows.
;WITH DirtyRows AS
(
SELECT * FROM [Table 1]
EXCEPT
SELECT * FROM [Table 2]
)
DELETE [Table 2]
WHERE EXISTS
(
SELECT * FROM DirtyRows
WHERE DirtyRows.Id = [Table 2].Id
)
Why would you want to do that with cursors?, If I understood you correctly, you can just do:
DELETE B
FROM table1 A
INNER JOIN table2 B
ON A.Id = B.Id
WHERE A.column1 <> B.column1 OR A.column2 <> B.Column2 ....
Or something like that.
Related
As an example I have a table in SQL Server :
Id
1
3
5
and I have a list of values 1,2,3
What is the query to select values of my list not in the table.
Expected result :
Id
2
Here are two approaches
Using Not Exists
Select *
from string_split('1,2,3',',') A
Where not exists ( select 1 from YourTable where ID=Value )
Using a LEFT JOIN
Select A.Value
from string_split('1,2,3',',') A
left Join YourTable B on A.value=B.ID
Where B.ID is null
Both Results are
Value
2
SELECT * FROM id_table WHERE id NOT IN (1,2,3);
Let's say that i have a stored procedure which returns all data from two tables: A and B.
Table_A
Id Name
-----------------
1 Chuck
2 Richard
3 Arthur
Table_B
Status Nickname IdTableA
-----------------------------
1 cthulhu 1
2 Poe 3
And the query:
SELECT
a.Name, b.Status, b.Nickname
FROM
Table_A a
LEFT JOIN
Table_B b ON b.IdTableA = a.Id
If I run the stored procedure right now, it returns all the records, even when they don't have a record in table_B (as you can see, record number 2 from table_A does not exist yet -maybe tomorrow, or in a month...-). What I need to do is discard the status number 2 (which lives on table B). The problem happens when I use something like:
where b.Status = 1
or
where b.Status <> 2
Why? Because it returns only the values with Status 1. I need only discard records with status 2, but return also the records from table_A without records on table_B.
There's a way to do that?
Hope you can help me. Thanks in advance.
Does the following screenshot fulfil your requirement?
try the following:
declare #table_a table (id int, name varchar(100))
insert into #table_a select 1, 'Chuck'
union select 2, 'Richard'
union select 3, 'Arthur'
declare #table_b table (status int, nickname varchar(100), id_table_a int)
insert into #table_b
select 1, 'cthulhu', 1
union select 2, 'Poe', 3
select * from #table_a
select * from #table_b
select *
from #table_a a
left join #table_b b on a.id = b.id_table_a
where isnull(status,'') <> 2
I have Table1
And I am trying to remove every identical Column A value if one of it's row has "ZX" anywhere in Column B. So if I did it right, it will look like Table2
I did the following:
Select
Column A,
Column B
From
Table1
Where
Column B not like '%ZX%'
However, it only removes rows with ZX and not every identical Column A values and returns this Table instead
I will really appreciate any help on this! Thank you in advance :)
You can use NOT IN
SELECT
ColumnA
, ColumnB
FROM table1
WHERE ColumnA NOT IN (SELECT ColumnA FROM table1 WHERE ColumnB like '%ZX%')
I like not exists for this purpose:
Select t1.*
From Table1 T1
where not exists (select 1 from table1 tt1 where tt1.a = t1.a and tt1.b like '%ZX%');
This can take advantage of an index on table1(a, b).
Use :NOT EXISTS and that should do it:
Select
[Column A],
[Column B]
From Table1 T1
where
NOT EXISTS (
SELECT 1 FROM TABLE1 T2
WHERE T2.[Column B] like '%ZX%'
AND T2.[column a] = t1.[column a]
)
I have three joins in my query. My requirement is to select records if either first two joins get satisfied or the third join gets satisfied
select * from security.requestview r
-- either below two joins satisfy
left join security.RequestDelegateView rd on r.id = rd.RequestId
join (select top 1 PersonnelNumber from SECURITY.MyRolesView) m on (m.PersonnelNumber=r.RequestorId or m.PersonnelNumber=r.InitiatorId or m.PersonnelNumber=rd.DelegatePersonnelNumber)
-- or this join
join (select substring(ltrim(DDSUCode),0,3) as Division from security.staffview where PersonnelNumber = (select top 1 PersonnelNumber from SECURITY.MyRolesView)) s
on r.OrganizationUnitRefId like s.Division+'%'
But ofcourse it will try to satisfy all the joins together.
Is there any way I can put some condition where it will select record if either first two joins satisfy or the last join alone satisfies?
Update
I tried putting them as where conditions but then the query is running forever
To answer this question:
Is there any way I can put some condition where it will select record
if either first two joins satisfy or the last join alone satisfies?
No, I know of no way to do this in a single query.
One way you can write this so that the third join only gets executed if the first one doesn't return records is in a multi-query series that populates a temp table or table variable:
INSERT INTO #tmp
SELECT (the first join);
IF (SELECT COUNT(*) FROM #tmp) = 0
INSERT INTO #tmp
SELECT (the second join);
SELECT * FROM #tmp;
WITH FirstJoin AS (
select * from security.requestview r
left join security.RequestDelegateView rd on r.id = rd.RequestId
join (select top 1 PersonnelNumber from SECURITY.MyRolesView) m on (m.PersonnelNumber=r.RequestorId or m.PersonnelNumber=r.InitiatorId or m.PersonnelNumber=rd.DelegatePersonnelNumber)
), SecondJoin AS (
select * from security.requestview r
join (select substring(ltrim(DDSUCode),0,3) as Division from security.staffview where PersonnelNumber = (select top 1 PersonnelNumber from SECURITY.MyRolesView)) s
on r.OrganizationUnitRefId like s.Division+'%'
), BothJoins AS (
SELECT * FROM FirstJoin
UNION ALL
SELECT * FROM SecondJoin
)
SELECT DISTINCT * FROM BothJoins
To get this to work you need to Change the "Select *" inside the CTE's so that every returned column is named. (Since I don't know whats in your tables I couldn't do it).
Please note that FirstJoin and SecondJoin needs to return the same columns.
select *
from table1
left join table2
on table1.id = table2.t1
left join table3
on table1.id = table3.t1
left join table4
on table1.id = table4.t1
where table2.t1 is not null
or table3.t1 is not null
or table4.t1 is not null
I'm working in SQL Server 2008. My goal is find all rows in table A that are not in table B. I also want to find all rows in table A where two certain conditions in table B are met. My basic query for the first part is:
SELECT
table_A.some_col
FROM table_A
LEFT JOIN table_B
ON table_A.A_key = table_B.B_key
WHERE
table_B.B_key IS NULL
To get the second part, my best guess is:
SELECT
table_A.some_col
FROM table_A
LEFT JOIN table_B
ON table_A.A_key = table_B.B_key
WHERE
table_B.B_key IS NULL
OR
table_B.another_col = 'some_value'
OR
table_B.yet_another_col = 'some_other_value'
However, this is giving me far more rows returned than expected. Do I need to fix this by using a UNION instead?
SELECT
table_A.some_col
FROM table_A
where not exists
( select * from table_B
where /* relationship */ table_A.A_key = table_B.B_key and /* any conditions you want */ table_B.B_key IS NULL and table_B.ColX = 'abc' )
OR
SELECT
table_A.some_col
FROM table_A
where not exists
( select * from table_B
where /* relationship */ table_A.A_key = table_B.B_key )
UNION ALL
SELECT
table_A.some_col
FROM table_A
where exists
( select * from table_B
where table_B.B_key IS NULL and table_B.ColX = 'abc' )
Post some DDL, some sample INSERTS and expected results if you want more defined than that.