Reputation: 31
I have a table like this:
id col1 col2
----------- ---- -----------
1 A 5
2 A 6
3 B 5
4 B 6
5 B 7
6 C 6
7 D 7
I need to select no more than one row with any exact value of col1
or col2
.
For example one possible solution is:
id col1 col2
----------- ---- -----------
1 A 5
4 B 6
7 D 7
Other possible solution is:
id col1 col2
----------- ---- -----------
3 B 5
6 C 6
7 D 7
I need to find one of any possible solutions.
The algorithm is very simple:
col1
equal to value of col1
or value in
col2
equal to value of col2
in the selected row. How to implement this logic in SQL SELECT
statement?
Code to generate test table:
CREATE TABLE #t (id INT IDENTITY, col1 CHAR(1), col2 INT) ;
INSERT INTO #t (col1, col2)
VALUES
('A', 5),
('A', 6),
('B', 5),
('B', 6),
('B', 7),
('C', 6),
('D', 7);
Upvotes: 1
Views: 1543
Reputation: 1
Try this query:
SELECT id, col1, col2
FROM ( SELECT * ,
RANK() OVER ( PARTITION BY col2 ORDER BY col2 ) Row#
FROM #t
) x
WHERE x.Row# = 1
Upvotes: 0
Reputation: 3744
try the following using cursor:
create table #final (id int, col1 varchar(10), col2 int)
declare @id int, @col1 varchar(10), @col2 int
declare cur cursor for select id, col1, col2 from #t order by newid()
open cur
fetch next from cur into @id, @col1, @col2
while @@FETCH_STATUS = 0
begin
if (@col1 in (select col1 from #final) or @col2 in (select col2 from #final))
begin
fetch next from cur into @id, @col1, @col2
continue
end
insert into #final
select id, @col1, @col2 from #t where col1 = @col1 and col2 = @col2 and id = @id
fetch next from cur into @id, @col1, @col2
end
close cur
deallocate cur
select * from #final order by id
drop table #final
Result:
Upvotes: 0
Reputation: 50034
This is not an easy one to solve through straight SQL. I figured I'd give it a crack using a recursive CTE. This spits out all possible combinations, but... in one field called "path" here. Perhaps it will present a way forward using straight tsql.
With recCTE AS
(
SELECT
col1,
col2,
0 as depth,
CAST(col1 + '|' + CAST(col2 AS varchar(10)) AS VARCHAR(30)) as path
FROM t
UNION ALL
SELECT
t1.col1,
t1.col2,
rec.depth + 1,
CAST(rec.path + '>' + t1.col1 + '|' + cast(t1.col2 as varchar(10)) as varchar(30))
FROM t t1
INNER JOIN recCTE rec
ON rec.path NOT LIKE '%|' + CAST(t1.col2 as varchar(10)) + '%'
AND rec.path NOT LIKE '%' + CAST(t1.col2 as varchar(10)) + '|%'
WHERE depth + 1 <= 3
)
SELECT *
FROM recCTE
WHERE depth = 2
Upvotes: 0
Reputation: 3141
SELECT id, col1, col2
FROM ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY col2 ORDER BY col2 ) Row#
FROM #t
) x
WHERE x.Row# = 1
Upvotes: 2