Thread: Matching columns in rows from two tables

Matching columns in rows from two tables

From
Richard Emberson
Date:
I have the following tables:

-- all of the users
-- user_id are unique
CREATE TABLE users (   user_id             BIGINT,   ....   PRIMARY KEY (user_id)
);
-- all of the groups
-- user_id are unique
CREATE TABLE groups (   group_id             BIGINT,   ...   PRIMARY KEY (group_id)
);
-- all of the group sets
-- group_set_id are unique
CREATE TABLE group_sets (   group_set_id        BIGINT,   ...   PRIMARY KEY (group_set_id)
);
-- a user can be a member of one or more groups
CREATE TABLE membership (   user_id             BIGINT,   group_id            BIGINT,   ....   FOREIGN KEY (user_id)
REFERENCESusers (user_id),   FOREIGN KEY (group_id) REFERENCES groups (group_id)
 
);

-- a group set is a set of one or more groups
CREATE TABLE group_sets (   group_id            BIGINT,   group_set_id        BIGINT,   ....   FOREIGN KEY (group_id)
REFERENCESgroups (group_id),   FOREIGN KEY (group_set_id) REFERENCES group_sets (group_set_id)
 
);

I want to:
   Find the group_set_id such that for a given user_id (input
parameter)   there is a one-to-one correspondence between the group_ids
associated   with the user_id and the group_ids associated with the group_set_id;
   for every group_id that the user_id has, the group_set_id also has
it   and for every group_id that the group_set_id has, the user_id also
has it.   If there is no such group_set_id, then return null.
   What query will generate the group_set_id?

There ought to be some combination of joins, intersections, etc. that
can generate the result
but I am getting hungup on the fact that the number of group_ids being
matched is not fixed.

Thanks for any help.

Richard



Re: Matching columns in rows from two tables

From
Masaru Sugawara
Date:
On Wed, 20 Feb 2002 13:51:12 -0800
Richard Emberson <emberson@phc.net> wrote:

> I have the following tables:
>
...

> -- a group set is a set of one or more groups
> CREATE TABLE group_sets (

Group_sets is already defined, isn't it ?

>     group_id            BIGINT,
>     group_set_id        BIGINT,
>     ....
>     FOREIGN KEY (group_id) REFERENCES groups (group_id),
>     FOREIGN KEY (group_set_id) REFERENCES group_sets (group_set_id)
> );
> 
> I want to:
>     Find the group_set_id such that for a given user_id (input parameter)
>     there is a one-to-one correspondence between the group_ids associated
>     with the user_id and the group_ids associated with the group_set_id;
> 
>     for every group_id that the user_id has, the group_set_id also has it
>     and for every group_id that the group_set_id has, the user_id also has it.
>     If there is no such group_set_id, then return null.
> 
>     What query will generate the group_set_id?

I'm not sure whether or not I have understood what you described.
If I use organizations instead of the 2nd group_sets you were created,
presumably ...


-- using no joins
select org1.group_set_id from organizations as org1where exists (select org0.group_id                from organizations
asorg0               where exists (select mem.group_id                               from membership as mem
                where org0.group_id = mem.group_id                                    and user_id = <<input parameter>>
                            group by mem.group_id                             having count(*) = 1
     )                     and org1.group_id = org0.group_id               group by org0.group_id              having
count(*)= 1              )
 
;

-- using inner joins
select org2.group_set_id from (select org0.group_id          from (select group_id from membership                where
user_id= <<input parameter>>                group by group_id               having count(*) = 1              ) as mem
          inner join organizations as org0              on (mem.group_id = org0.group_id)        group by org0.group_id
     having count(*) = 1      ) as org1      inner join organizations as org2      on (org1.group_id = org2.group_id)
 
;


Regards,
Masaru Sugawara



Re: Matching columns in rows from two tables

From
Masaru Sugawara
Date:
On Sat, 23 Feb 2002 08:03:19 -0800
Richard Emberson <emberson@phc.net> wrote:

> Thank you very much for your help. I managed to create a query with only two select
> statements
> and none of the selects are inner-selects:
> 
> SELECT group_set_id, count(*) FROM group_sets , membership
> WHERE membership.user_id = <<input parameter>>
> AND membership.group_id = group_sets.group_id
> GROUP BY group_set_id
> INTERSECT
> SELECT group_set_id, count(*) FROM group_sets
> GROUP BY group_set_id;
> 
> There may still be a better (better performance) query,

Quite so.   I would think it's probably one of the best way.  Practically,I found my query including "where exists/not
exists"is awfully slow if thereare about 1000+ rows.
 


> but, again, this is the
> best I could
> come up with.
> 
> Thanks.
> 
> Richard
> 
> > On Wed, 20 Feb 2002 13:51:12 -0800
> > Richard Emberson <emberson@phc.net> wrote:
> >
> > > I have the following tables:
> > >
> >
> >  ...
> >
> > > -- a group set is a set of one or more groups
> > > CREATE TABLE group_sets (



Regards,
Masaru Sugawara