【问题标题】:How to get list of step siblings in postgres?如何在postgres中获取步骤兄弟姐妹的列表?
【发布时间】:2018-09-19 22:56:22
【问题描述】:

以下是我的架构:-

postgres=# \d check_user;
                         Table "public.check_user"
 Column |  Type   |                        Modifiers
--------+---------+---------------------------------------------------------
 id     | integer | not null default nextval('check_user_id_seq'::regclass)
 name   | text    |
 gender | text    |
Indexes:
    "check_user_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "parent" CONSTRAINT "parent_left_node_fkey" FOREIGN KEY (left_node) REFERENCES check_user(id)
    TABLE "parent" CONSTRAINT "parent_right_node_fkey" FOREIGN KEY (right_node) REFERENCES check_user(id)
    TABLE "spouse" CONSTRAINT "spouse_husband_fkey" FOREIGN KEY (husband) REFERENCES check_user(id)
    TABLE "spouse" CONSTRAINT "spouse_wife_fkey" FOREIGN KEY (wife) REFERENCES check_user(id)


postgres=# \d parent;
                           Table "public.parent"
   Column   |  Type   |                      Modifiers
------------+---------+-----------------------------------------------------
 id         | integer | not null default nextval('parent_id_seq'::regclass)
 left_node  | integer |
 right_node | integer |
Indexes:
    "parent_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "parent_left_node_fkey" FOREIGN KEY (left_node) REFERENCES check_user(id)
    "parent_right_node_fkey" FOREIGN KEY (right_node) REFERENCES check_user(id)

postgres=# \d spouse
                          Table "public.spouse"
 Column  |  Type   |                      Modifiers
---------+---------+-----------------------------------------------------
 id      | integer | not null default nextval('spouse_id_seq'::regclass)
 husband | integer |
 wife    | integer |
Indexes:
    "spouse_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "spouse_husband_fkey" FOREIGN KEY (husband) REFERENCES check_user(id)
    "spouse_wife_fkey" FOREIGN KEY (wife) REFERENCES check_user(id)

以下是每个表格中的数据:-

postgres=# select * from check_user;
 id | name | gender
----+------+--------
  4 | a    | m
  1 | x    | m
  2 | y    | f
  3 | z    | f
  7 | c3   | f
  6 | c2   | m
  5 | c1   | m
  8 | b    | m
  9 | c4   | f
(9 rows)

postgres=# select * from spouse;
 id | husband | wife
----+---------+------
  1 |       1 |    2
  2 |       1 |    3
  3 |       4 |    2
  4 |       8 |    3
(4 rows)

postgres=# select * from parent;
 id | left_node | right_node
----+-----------+------------
  1 |         1 |          5
  2 |         2 |          5
  3 |         1 |          6
  4 |         3 |          6
  5 |         4 |          7
  6 |         2 |          7
  7 |         8 |          9
  8 |         3 |          9

现在,我想找到用户 c1 的步骤兄弟姐妹。我所说的继兄弟是指用户是 c1 的父亲的母亲的儿子,但不是两者兼有。

我正在使用以下查询:-

 with user_parents as (
    select  child.id as child_id, child.name as child_name, parent_dtls.id as parent_id,
parent_dtls.name as parent_name, child.gender as child_gender, parent_dtls.gender as parent_gender
from check_user child
        inner join parent on child.id=parent.right_node
        inner join check_user parent_dtls on parent.left_node=parent_dtls.id
    ),
fathers as (select * from user_parents where user_parents.parent_gender='m'),
mothers as (select * from user_parents where user_parents.parent_gender='f'),
my_father as (select * from fathers where fathers.child_id=5),
my_mother as (select * from mothers where mothers.child_id=5)
select   user_.id as "user_id", fathers.parent_id as "father_id", my_father.parent_id "my_father_id",
mothers.parent_id as "mother_id", my_mother.parent_id as "my_mother_id" from parent parent_dtls
left join my_father on parent_dtls.left_node=my_father.parent_id
left join my_mother on parent_dtls.left_node=my_mother.parent_id
inner join check_user user_ on user_.id=parent_dtls.right_node
left join fathers on parent_dtls.right_node=fathers.child_id
left join mothers on parent_dtls.right_node=mothers.child_id where my_father.parent_id is null and my_mother.parent_id is null;

但我得到了其他行以及继兄弟姐妹。

我做错了什么?此外,如果上面查询中存在效率低下的问题,请发表评论。

提前致谢。

【问题讨论】:

标签: sql postgresql hierarchical-data family-tree


【解决方案1】:

我更喜欢逐步解决任务。所以代码是这样的:

//select the child id with child_id as ( select id from check_user where name = 'c1'), //select parents ids parents as ( select left_node, right_node from parent where id in (select * from child_id) ) select * from check_user where id in ( select id from parent where //child of one parents, not both (left_node in (select left_node from parents) and right_node not in (select right_node from parents)) or (left_node not in (select left_node from parents) and right_node in (select right_node from parents) ) )

附言 看来,根据任务描述,配偶表是不必要的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-08-29
  • 2014-09-20
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 2013-01-06
  • 1970-01-01
相关资源
最近更新 更多