I want to remove duplicates based on below condition.
My table contains data like cross relation. Column 1 value exist in column 2 and vice versa.
sample table
id id1
-------------
1 2
2 1
3 4
4 3
5 6
6 5
7 8
8 7
I want to delete 1 row from first two rows, same from third and forth, same for fifth and sixth and so on..
Can anyone please help?
Like this way you are going to delete just the second row from each group of 2 rows:
CREATE TABLE [LIST_ID](
[ID] [NUMERIC](4, 0) NOT NULL,
[ID_1] [NUMERIC](4, 0) NOT NULL
);
INSERT INTO LIST_ID (ID, ID_1)
VALUES
(1, 2),
(2, 1),
(3, 4),
(4, 3),
(5, 6),
(6, 5);
WITH First_Row AS
(
SELECT ROW_NUMBER() OVER (ORDER BY ID ASC) AS Row_Number, *
FROM LIST_ID
)
DELETE FROM First_Row WHERE Row_Number % 2 ='0';
SELECT * FROM LIST_ID;
How about this:
DELETE
FROM myTable
WHERE id IN (
SELECT CASE WHEN id < id1 THEN id ELSE id1 END
FROM myTable
)
Where myTable is the sample table with data.
declare #t table (id1 int, id2 int)
insert into #t (id1, id2)
values
(1, 2),
(2, 1),
(2, 1),
(2, 1),
(3, 4),
(3, 4),
(5, 6),
(7, 8),
(7, 6),
(6, 7),
(5, 0)
delete t2
from #t t1
inner join #t t2 on t2.id1 = t1.id2 and t2.id2 = t1.id1
where t2.id1 > t1.id1
select * from #t order by 1, 2
declare #t table (id1 int, id2 int)
insert into #t (id1, id2)
values
(1, 2),
(2, 1),
(3, 4),
(4, 3),
(5, 6),
(6, 5),
(7, 8),
(8, 7)
;
;with a as (
select
row_number() over (order by id1) rn
,t.id1
,t.id2
from
#t t
)
delete t from
#t t
join (
select
a.id1
,a.id2
from
a a
where
exists(
select
*
from
a b
where
a.id2 = b.id1 and a.id1 = b.id2 and a.rn > b.rn
)
) c on t.id1 = c.id1 and t.id2 = c.id2
;
select * from #t;
/* OUTPUT
id1 id2
1 2
3 4
5 6
7 8
*/
It'll vary a little based on which row you want to keep, but if you really have simple duplicates as in your example, and every pair exists in both orders, this should do it:
DELETE FROM MyTable
WHERE ID > ID1
So what i could understand you want to delete the rows from table where id = id1.
delete from TableA as a
where exists(select 1 from TableA as b where a.id = b.id1)
Related
I have a table that contains IDs from two other tables. Those are two integer numbers.
CustomerId SectionId
====================
1 1
1 2
1 3
2 2
2 3
3 1
3 2
3 3
4 2
4 3
What I am looking for is for those records that have the SectionId=1 missing. For the above example I need to retrieve CustomerId 2 and 4.
I cannot do a Select customer ID where SectionId <> 1 because it will bring me all records (1 to 4). I specifically need those that, independently of which SectionId they have, are missing SectionId=1
Thanks.
You need NOT EXISTS:
SELECT DISTINCT t1.CustomerId
FROM tablename t1
WHERE NOT EXISTS (SELECT 1 FROM tablename t2 WHERE t2.CustomerId = t1.CustomerId AND t2.SectionId = 1)
Or, with conditional aggregation:
SELECT CustomerId
FROM tablename
GROUP BY CustomerId
HAVING COUNT(CASE WHEN SectionId = 1 THEN 1 END) = 0
Try this
select distinct id
from Test
where id not in (
select distinct id
from Test
where section = 1
);
check 2 examples
Declare #t Table (CustomerId int, SectionId int)
insert into #t Values
(1, 1),
(1, 2),
(1, 3),
(2, 2),
(2, 3),
(3, 1),
(3, 2),
(3, 3),
(4, 2),
(4, 3)
select DISTINCT CustomerId from #t
where CustomerId not in (
select CustomerId from #t
where SectionId = 1
group by CustomerId
)
SELECT DISTINCT t1.CustomerId
FROM #t t1
WHERE NOT EXISTS (SELECT * FROM #t t2
WHERE t2.CustomerId = t1.CustomerId AND t2.SectionId = 1)
Table 1
Code Division IsActive Company
A A 1 Test1
B B 1 Test1
C C 1 Test1
D D 1 Test2
E E 1 Test2
F F 1 Test2
Trascation Table2
Code Division
1 A
2 B
3 C
4 D
5 A,B
6 E,f
7 E
8 F
Select * from table2 where (Select code from table1 where company = 'Test1') -- with this query i cant get the columns (5(A,B)) and 6(E,F))
So i tweaked the query to :
Select
*
from table2
where
(Select
code
from table1
where
contains(code, 'A')
or
contains(code, 'B')
)
I dont want to hard code the values(Divisions) how can i pass through Parameter!!
You can do this with STRING_SPLIT from SQL Server 2016:
declare #table1 table (Code char(2), Division char(2), IsActive bit, Company nvarchar(100))
insert into #table1 values
('A', 'A', 1, 'Test1')
, ('B', 'B', 1, 'Test1')
, ('C', 'C', 1, 'Test1')
, ('D', 'D', 1, 'Test2')
, ('E', 'E', 1, 'Test2')
, ('F', 'F', 1, 'Test2')
declare #table2 table (Code char(2), Division varchar(100))
insert into #table2 values
(1, 'A')
, (2, 'B')
, (3, 'C')
, (4, 'D')
, (5, 'A,B')
, (6, 'E,f')
, (7, 'E')
, (8, 'F')
SELECT distinct t2.*
FROM #table2 t2
cross apply string_split(t2.Division, ',')
inner join #table1 t1 on t1.Division = [value]
where t1.Company = 'Test1'
SELECT t1.*, t2.*, [value] as Table2Division
FROM #table2 t2
cross apply string_split(t2.Division, ',')
inner join #table1 t1 on t1.Division = [value]
I added this to my stored procedure and that resolved my issue
INNER JOIN [dbo].[tbl_division] division ON folder.divisions like concat ('%', division.code , '%')
WHERE folder.[StatusCode] > 0 AND viewFolderItem.[StatusCode] > 0 And division.company = 'Test1'
DECLARE #Table1 TABLE
(ID int, STATUS varchar(1))
;
INSERT INTO #Table1
(ID, STATUS)
VALUES
(1, 'A'),
(1, 'A'),
(1, 'A'),
(1, 'B'),
(1, 'A'),
(2, 'C'),
(2, 'C')
;
Script :
Select *,ROW_NUMBER()OVER(PARTITION BY STATUS ORDER BY (SELECT NULL))RN from #Table1
Getting Result Set
ID STATUS RN
1 A 1
1 A 2
1 A 3
1 A 4
1 B 1
2 C 1
2 C 2
Need Output
ID STATUS RN
1 A 1
1 A 2
1 A 3
1 B 1
1 A 1
2 C 1
2 C 2
Try this
DECLARE #Table1 TABLE
(ID int, STATUS varchar(1));
INSERT INTO #Table1
(ID, STATUS)
VALUES
(1, 'A'),
(1, 'A'),
(1, 'A'),
(1, 'B'),
(1, 'A'),
(2, 'C'),
(2, 'C');
;WITH Tmp
AS
(
SELECT *, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNumber FROM #Table1
)
SELECT
A.ID ,
A.STATUS ,
ROW_NUMBER() OVER (PARTITION BY A.STATUS, (A.RowNumber - A.RN) ORDER BY (SELECT NULL)) AS RN
FROM
(
Select *, ROW_NUMBER() OVER(PARTITION BY STATUS ORDER BY RowNumber) AS RN from tmp
) A
ORDER BY
A.RowNumber
Output:
ID STATUS RN
----------- ------ ------
1 A 1
1 A 2
1 A 3
1 B 1
1 A 1
2 C 1
2 C 2
Firstly, In the insert statement that you posted. How is 4 different from 1,2 and 3, if it is based on a different column then include that column as well in "row_number" in partition by sub clause. Because otherwise it will think that 'A' in 4 and 'A' in 1,2,3 are same and therefore group them together.
INSERT INTO #Table1
(ID, STATUS)
VALUES
(1, 'A'), <-- 1
(1, 'A'), <-- 2
(1, 'A'), <-- 3
(1, 'B'),
(1, 'A'), <-- 4
(2, 'C'),
(2, 'C')
;
SQL Query for Select Sequence Numbers
In SQL server, I want to select rows based on sequence numbers. For example I am having data as below:
ID RowNos
A 1
B 2
X NULL
C 4
D 5
Y NULL
E 7
F 8
G 9
H 11
I 13
Query Should return
ID NextID
A B -- Since RowNos 1,2 is in sequence
C D -- Since RowNos 4,5 is in sequence
E G -- Since RowNos 7,8,9 is in sequence
I don't have idea to start this query. Otherwise I'll post my trial too.
DECLARE #t TABLE (ID CHAR(1), RowNos INT)
INSERT INTO #t
VALUES
('A', 1), ('B', 2), ('X', NULL),
('C', 4), ('D', 5), ('Y', NULL),
('E', 7), ('F', 8), ('G', 9),
('H', 11), ('I', 13)
SELECT MIN(ID), MAX(ID)
FROM (
SELECT *, rn = ROW_NUMBER() OVER (ORDER BY RowNos)
FROM #t
) t
WHERE RowNos IS NOT NULL
GROUP BY RowNos - rn
HAVING MIN(ID) != MAX(ID)
Output:
---- ----
A B
C D
E G
to select them ordered should be something like:
SELECT * FROM table_name WHERE RowNos IS NOT NULL ORDER BY RowNos ASC;
I have table mentioned below (id and Loc are Primary Keys)
ID LOC RNK NBR1 NBR2
1 2 A 10 b --->
3 4 A 10 b --->
5 6 A 11 C
8 2 A 12 D
6 3 A 10 b --->
SO here I have to fetch only duplicate records according to NBR1 and NBR2, It should fetch all the records not only the duplicates(marked as --->).
If I understood your question correctly you can do it with a subquery
CREATE TABLE #Test (ID int, LOC int, RNK char(1), NBR1 int, NBR2 char(1) )
INSERT INTO #Test VALUES
(1, 2, 'A', 10, 'b'),
(3, 4, 'A', 10, 'b'),
(5, 6, 'A', 11, 'C'),
(8, 2, 'A', 12, 'D'),
(6, 3, 'A', 10, 'b')
SELECT *
FROM #Test t1
WHERE EXISTS
(SELECT 1
FROM #Test t2
WHERE t1.NBR1 = t2.NBR1
AND t1.NBR2 = t2.NBR2
GROUP BY NBR1, NBR2
HAVING COUNT(1) > 1)
You can also use this, but cost will be more. The RowsCount having values greater than 1 are duplicate and having values 1 are unique records.
With Temp As
(
Select ID,LOC,RNK,NBR1,NBR2,Row_NUMBER() OVER (PARTITION BY NBR2 ORDER BY NBR1) AS ROWSCOUNT FROM <<TABLE_NAME>>
)
Select * from Temp