列出从特定用户到尚未审核的其他用户的所有行程

时间:2012-08-05 13:40:28

标签: sql postgresql

我正在使用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行。

如果驾驶员对passenger1进行了审核,并再次运行查询,则不会返回任何内容。

对于乘客来说,如果我想乘坐尚未经过检查的乘客2的所有乘客1,我将获得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

3 个答案:

答案 0 :(得分: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
      ) ;

答案 1 :(得分:1)

如果接受任何数量的评论作为评审行程,则应该这样做。

SELECT * from trips 
where t.id not in 
    (SELECT distinct(t.id)
    FROM trips t, feedbacks f
    WHERE t.id = f.trip_id)

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

答案 2 :(得分: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