如何连接表并检索包含父信息或子信息的记录,但不能同时检索两者?

时间:2014-08-07 10:30:31

标签: sql postgresql

所有

我需要帮助查找复杂情况的查询。

假设我有以下数据库结构(构造与我们目前的相似):

保留

booking_code | description
-------------+-------------
alpha        | alpha code
beta         | beta code
gamma        | gamma code
omega        | omega code

宾客

name        | booking_code   | parent_booking_code
------------+----------------+----------------------
andrew      | alpha          | -
kelvin      | beta           | -
michael     | -              | beta
nancy       | -              | beta
olaf        | gamma          | -
patricia    | -              | gamma
quincy      | -              | omega
raphael     | kappa          | -
stanley     | -              | kappa
timmy       | -              | delta

创建上述的SQL查询:

CREATE TABLE reservations (
   booking_code VARCHAR(15),
   description VARCHAR(15)
);

INSERT INTO reservations VALUES
('alpha', 'alpha code'), ('beta', 'beta code'), ('gamma', 'gamma code'), ('omega', 'omega code') ;

CREATE TABLE guests (
    name VARCHAR(20),
    booking_code VARCHAR(15),
    parent_booking_code VARCHAR(15)
);

INSERT INTO guests VALUES
('andrew', 'alpha', '-'), ('kelvin', 'beta', '-'), ('michael', '-', 'beta'), ('nancy', '-', 'beta'),
('olaf', 'gamma', '-'), ('patricia', '-', 'gamma'), ('quincy', '-', 'omega'), ('raphael', 'kappa', '-'),
('stanley', '-', 'kappa'), ('timmy', '-', 'delta') ;

从这里开始,我需要找到至少一个人booking_codeparent_booking_code指定reservations。我想避免重复的预订代码,因此,如果一个人已经拥有booking_code,请不要寻找具有相同parent_booking_code的其他人,反之亦然。

根据以上信息,我需要找到:

   name   | code
----------+-------
 andrew   | alpha
 kelvin   | beta
 olaf     | gamma
 quincy   | omega

这是我试过的:

SELECT
    guests.name,
    reservations.booking_code AS code
FROM
    reservations
JOIN
    guests ON
        reservations.booking_code = guests.booking_code OR
        reservations.booking_code = guests.parent_booking_code

GROUP BY name, code
ORDER BY name ;

/*
   name   | code
----------+-------
 andrew   | alpha
 kelvin   | beta
 michael  | beta
 nancy    | beta
 olaf     | gamma
 patricia | gamma
 quincy   | omega
(7 rows)
*/

试验2:

SELECT
    guests.name,
    reservations.booking_code AS code
FROM
    reservations
JOIN
    guests ON
        reservations.booking_code = guests.booking_code
JOIN
    guests AS g2 ON
        reservations.booking_code = g2.parent_booking_code

GROUP BY guests.name, code
ORDER BY guests.name ;

/*
  name  | code
--------+-------
 andrew | alpha
 kelvin | beta
 olaf   | gamma
        |
(4 rows)
*/

试验3(改编自this SO answer):

SELECT
    reservations.booking_code AS code,
    g1.name
FROM
    reservations
JOIN
    guests AS g1 ON
        reservations.booking_code = g1.booking_code
INNER JOIN
    (
        SELECT name, parent_booking_code
        FROM guests
        GROUP BY name, parent_booking_code
    )
    AS g2 ON
        g2.name = g1.name AND g2.parent_booking_code = g1.parent_booking_code
INNER JOIN
    guests AS g3 ON
        g1.parent_booking_code = g3.booking_code

GROUP BY g1.name, code
ORDER BY g1.name ;

/*
 code  |  name
-------+--------
 alpha | andrew
 beta  | kelvin
 gamma | olaf
(3 rows)
*/

我试图从找到on this forum的解决方案中借用,但我无法找到将其应用于我的情况的方法,因为在该示例中,“code”在查询中指定({{1在我的情况下,它是parent_id表中的条目的一部分。

。})

感谢任何帮助。提前谢谢。

附加说明:如果重要的话我们正在使用postgresql。

1 个答案:

答案 0 :(得分:0)

尝试这个简单的查询:

SELECT
    MIN(guests.name) AS name,
    reservations.booking_code AS code
FROM
    reservations
JOIN
    guests ON
        reservations.booking_code = guests.booking_code OR
        reservations.booking_code = guests.parent_booking_code
GROUP BY code
ORDER BY name;