2

我正在使用 PostgreSQL。我有以下架构:

CREATE TABLE users (
  id int PRIMARY KEY
);

CREATE TABLE trips (
  id int PRIMARY KEY,
  driver_id int,
  FOREIGN KEY driver_id REFERENCES users(id)
);

CREATE TABLE trip_passengers (
  id int PRIMARY KEY,
  user_id int,
  trip_id int,
  FOREIGN KEY trip_id REFERENCES trips(id)
  FOREIGN KEY user_id REFERENCES users(id)
);

CREATE TABLE feedbacks (
  id int PRIMARY KEY,
  trip_id int,
  rater_id int,
  ratee_id int,
  review TEXT,
  FOREIGN KEY trip_id REFERENCE trips(id),
  FOREIGN KEY rater_id REFERENCES users(id),
  FOREIGN KEY ratee_id REFERENCES users(id),
  UNIQUE (trip_id, rater_id, ratee_id)
);

以下是以下规则:

  • 旅行可以包含多个乘客(通过 trip_passengers 表)。
  • 如果他们一起旅行,用户只能进行评论。
  • 司机可以对乘客进行评论。
  • 乘客也可以对司机进行评论。
  • 乘客可以对乘客进行评论。

案例:

表:用户

| id  | username   |
|-----+------------+
| 1   | driver     |
| 2   | passenger1 |
| 3   | passenger2 |

表:行程

| id  | driver_id |
|-----+-----------+
| 1   | 1         |

表:trip_passengers

| id  | trip_id | user_id |
|-----+---------+---------+
| 1   | 1       | 2       |
| 2   | 1       | 3       |

假设我想从尚未审查的乘客 1 的司机那里获得所有旅行。那将返回行程#1。

如果司机对乘客 1 进行评论,然后再次运行查询,它将不会返回任何内容。

乘客的情况相同,如果我想获得乘客 1 和乘客 2 尚未审查的所有行程,我将获得行程 #1,因为他们都乘坐相同的行程。

如何将特定用户的所有行程返回给尚未审核的其他用户?

这是我最后一次尝试,但有些情况没有遇到。

SELECT trips.* FROM trips
  INNER JOIN trip_passengers AS t1 ON t1.trip_id = trips.id
  INNER JOIN trip_passengers AS t2 ON t1.passenger_id = :rater_id AND
    t2.passenger_id = :ratee_id AND t1.trip_id = t2.trip_id
  LEFT JOIN feedbacks ON feedbacks.trip_id = trips.id AND
    feedbacks.rater_id = t1.passenger_id
  WHERE feedbacks.review IS NULL
4

3 回答 3

2

使用这种设计,您的要求不会被强制执行。任何用户都可以为任何其他用户提供反馈,无论评论者或被评论者是否参加了旅行!

这是一个建议:

用户

CREATE TABLE users
( user_id int PRIMARY KEY
) ;

旅行

CREATE TABLE trips
( trip_id int PRIMARY KEY
) ;

Trip_participants(乘客和司机)

CREATE TABLE trip_participants
( trip_id int,
  user_id int,
  PRIMARY KEY (trip_id, user_id),
  FOREIGN KEY trip_id REFERENCES trips (trip_id),
  FOREIGN KEY user_id REFERENCES users (user_id)
) ;

Trip_drivers

CREATE TABLE trip_drivers
( trip_id int,
  driver_id int,
  PRIMARY KEY (trip_id, driver_id),
  UNIQUE KEY (trip_id)                -- optional, to enforce that a trip
                                      -- has only one driver.
  FOREIGN KEY (trip_id, driver_id) 
    REFERENCES trip_participants (trip_id, user_id)
) ;

反馈

CREATE TABLE feedbacks
( feedback_id int PRIMARY KEY,
  trip_id int,
  rater_id int,
  ratee_id int,
  review TEXT,
  UNIQUE KEY (trip_id, rater_id, ratee_id) ,
  FOREIGN KEY (trip_id, rater_id) 
    REFERENCES trips(trip_id, user_id),
  FOREIGN KEY (trip_id, ratee_id) 
     REFERENCES trips(trip_id, user_id),
  CHECK (rater_id <> ratee_id)
) ;

缺少的trip_passengers是一个视图:

Trip_passengers

CREATE VIEW trip_passengers AS
  SELECT trip_id, user_id
  FROM trip_participants
  WHERE (trip_id, user_id) NOT IN
        ( SELECT trip_id, driver_id
          FROM trip_drivers
        ) 
;

最后,返回所有尚未审核的行程的查询:

SELECT t.*
FROM trips AS t
WHERE t.trip_id NOT IN
      ( SELECT trip_id 
        FROM feedbacks
      ) ;
于 2012-08-05T14:12:12.223 回答
1

如果任何数量的评论被接受为已评论的旅行,那么应该这样做。

从旅行中选择 *
t.id 不在的地方
    (选择不同的(t.id)
    FROM 行程 t,反馈 f
    其中 t.id = f.trip_id)

使用子查询选择所有已审核的行程,然后选择不在已审核行程中的行程。

于 2012-08-05T13:57:49.757 回答
1

尝试这个:

SELECT  a.*
FROM    trips a
            INNER JOIN  feedbacks f
                on a.ID = b.trip_id
            LEFT JOIN trips c
                on a.ID = c.ID
WHERE   c.ID IS NULL
于 2012-08-05T14:07:47.907 回答