469,890 Members | 2,154 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,890 developers. It's quick & easy.

SQL gurus, please help

Raj
Hi,

I have a table in which two fields(FirstID, SecondID) together make the
primary key for the table. Let's look at the following example:

FirstID SecondID
******* ********
2 2
2 3
2 5
5 5
5 7
8 7
9 10
11 12

Here is what I am trying to do. For a given FirstID (say, 2) find all
SecondID with this FirstID (2,3,5). Now for these second ID's is there
a FirstID other than 2? (Yes, 5). I would say FirstID=2 is related to
FirstID = 5. Extending the logic FirstID = 5 is related to FirstID = 8.
I am trying to write a SQL (some kind of self join, I think) which will
give me all related FirstID for a given First ID. For First ID = 2 the
SQL will give me 5 and 8 in the above example. For First ID = 9 the SQL
will give me 11.
Any help will be greatly appreciated. Thanks!!

-Raj

Jul 23 '05 #1
6 1121
Without knowing exactly what you are doing or seeing the complete
design, including keys, it's difficult to suggest whether a different
design might help here. Don't these "IDs" actually reference other
tables? Are we dealing with one or two entities here? Google this group
and microsoft.public.sqlserver.programming for many other solutions and
examples of Trees and Hierarchies.

If the design is fixed then you'll have to do this iteratively, unless
you can set some upper bound on the number of levels, in which case it
should be possible using a fixed number of self-outer joins.

See also this post, which solves a similar problem:

http://www.google.co.uk/groups?selm=...40giganews.com

--
David Portas
SQL Server MVP
--

Jul 23 '05 #2
create table TestIDs(FirstID int not null,SecondID int not null,
primary key(FirstID,SecondID))
insert into TestIDs(FirstID,SecondID) values(2,2)
insert into TestIDs(FirstID,SecondID) values(2,3)
insert into TestIDs(FirstID,SecondID) values(2,5)
insert into TestIDs(FirstID,SecondID) values(5,5)
insert into TestIDs(FirstID,SecondID) values(5,7)
insert into TestIDs(FirstID,SecondID) values(8,7)
insert into TestIDs(FirstID,SecondID) values(9,10)
insert into TestIDs(FirstID,SecondID) values(11,12)

select t1.FirstID as ID,t2.FirstID as RelatedID
from TestIDs t1
inner join TestIDs t2 on t2.SecondID=t1.SecondID and
t2.FirstID<>t1.FirstID
order by t1.FirstID,t2.FirstID

I think your sample data is wrong for First ID = 9, try adding

insert into TestIDs(FirstID,SecondID) values(11,10)
Jul 23 '05 #3
Raj
Thank you David and Mark for your input. I have looked into both of
your solutions but neither one of them does what I am looking for. I
will describe in detail like what I am looking for. Let me first
apologize for the typo in the last line in my original post. Here is
the correct sample data with meaningful field names. I will describe
them in a second here:
create table test(property int, loan int);
insert into test values (2,2);
insert into test values (2,3);
insert into test values (2,5);
insert into test values (5,5);
insert into test values (5,7);
insert into test values (8,7);
insert into test values (9,10);
insert into test values (11,10);
Every property can have many loans associated with it. Similarly, a
single loan can be taken against bunch of properties. (Say, loan is for

a big amount and single property value is not enough). Hopefully the
sample data above now makes sense. So combination of property and loan
makes the primary key for the table. There are bunch of other fields in

the table which doesn't matter for what we are trying to do here. Also,

this is just one table and we are not talking about this linking to
another table or any thing like that. That will keep it simple. Now I
am trying to see if property 2 is related to other properties either
directly or indirectly. Prop 2 has loans 2, 3, 5. I will now check if
these loans (2,3,5) has any other properties other than 2. Yes, we have

property 5. I would call property 2 is related to property 5. Now
extending the logic, here in this case property 5 has loans 5, 7. Now
let's check if loans 5, 7 has any other properties (other than the ones

we already identified, i.e. 2,5). Yes, we have property 8. I would say
prop 8 is related to prop 5 directly, and prop 8 is related to prop 2
indirectly through 5. It doesn't matter whether they are related
directly or indirectly. I am interested in all of them. There is no
limit on how deep it can go. It is like we have property pool and loan
pool. We are finding if they are related.
Here is the result set I am envisioning. If I am intersted in finding
related properties for prop 2, probably a tabular result as follows
will give me what I am looking for:
Given Property Related Properties
2 2
2 5
2 8
Similarly for prop 9,
Given Property Related Properties
9 9
9 11
It doesn't matter whether we show each property related to itself or
not. Whatever works for you. I hope I am clear this time. I can write a

program to do this (with recordsets and looping etc) but there should
be a cool way of doing this with just the SQL. I just can't figure it
out. Your input will be greatly appreciated.
-Raj

Jul 23 '05 #4
> I can write a

program to do this (with recordsets and looping etc) but there should
be a cool way of doing this with just the SQL. I just can't figure it
out. Your input will be greatly appreciated.

-Raj


Well, there's no "cool way of doing it just with SQL" that I can think of,
except iterative. Here's a table-returning UDF that does what you want.
For large sets, you have *got* to have indexes on the test.property and
test.loan columns.

create function dbo.FindRelated
( @GivenProperty int )
returns @properties table (property int)
AS

BEGIN
declare @loans table (loan int)

insert into @properties values (@GivenProperty)

declare @n int
set @n = 1

while @n > 0
BEGIN
set @n = (select count(distinct dbo.test.loan) from dbo.test, @properties
P
where dbo.test.property=P.property
and not exists (select * from @loans L where L.loan = dbo.test.loan))
if @N = 0
break
insert into @loans
select distinct loan from dbo.test, @properties P
where dbo.test.property=P.property
and not exists (select * from @loans L where L.loan = dbo.test.loan)

set @n = (select count(distinct dbo.test.property) from dbo.test, @loans
L
where dbo.test.loan = L.loan
and not exists (select * from @properties P where P.property =
dbo.test.property))
if @N = 0
break
insert into @properties
select distinct property from dbo.test, @loans L
where dbo.test.loan = L.loan
and not exists (select * from @properties P where P.property =
dbo.test.property)
END
return
END
go

Sample executions:

select * from test
select 2 GivenProperty, property RelatedProperty from dbo.FindRelated(2) F
select 5 GivenProperty, property RelatedProperty from dbo.FindRelated(5)
select 9 GivenProperty, property RelatedProperty from dbo.FindRelated(9)

property loan
----------- -----------
2 2
2 3
2 5
5 5
5 7
8 7
9 10
11 10

GivenProperty RelatedProperty
------------- ---------------
2 2
2 5
2 8

GivenProperty RelatedProperty
------------- ---------------
5 5
5 2
5 8

GivenProperty RelatedProperty
------------- ---------------
9 9
9 11

Jul 23 '05 #5
select GivenProperty,RelatedProperty
from (
select f1.property as GivenProperty,b1.property as RelatedProperty
from test f1
inner join test b1 on b1.loan=f1.loan

union

select f1.property,b2.property
from test f1
inner join test b1 on b1.loan=f1.loan
inner join test f2 on f2.property=b1.property
inner join test b2 on b2.loan=f2.loan

union

select f1.property,b3.property
from test f1
inner join test b1 on b1.loan=f1.loan
inner join test f2 on f2.property=b1.property
inner join test b2 on b2.loan=f2.loan
inner join test f3 on f3.property=b2.property
inner join test b3 on b3.loan=f3.loan

union

select f1.property,b4.property
from test f1
inner join test b1 on b1.loan=f1.loan
inner join test f2 on f2.property=b1.property
inner join test b2 on b2.loan=f2.loan
inner join test f3 on f3.property=b2.property
inner join test b3 on b3.loan=f3.loan
inner join test f4 on f4.property=b3.property
inner join test b4 on b4.loan=f4.loan

) as Deriv
--where GivenProperty=2
order by GivenProperty,RelatedProperty

I can't see a way of doing this in a single SQL statement if you don't
know the maximum level of nesting in advance

HTH
Jul 23 '05 #6
Raj
Thank you Ross and Mark for your help. Ross's solution is preferable in
my case since I don't know the maximum level of testing. I did try it
out and it works.
Thanks again!!

-Raj

Jul 23 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by please | last post: by
2 posts views Thread by c++ newbie | last post: by
13 posts views Thread by Andrew Bell | last post: by
reply views Thread by =?Utf-8?B?YXZucmFv?= | last post: by
1 post views Thread by Waqarahmed | last post: by
reply views Thread by Salome Sato | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.