不同的JOIN类型可以给出相同的结果吗?

时间:2016-03-04 19:43:24

标签: sql postgresql join

我有以下架构:

CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  name VARCHAR(40) NOT NULL,
  email VARCHAR(255) NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE sitters (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID REFERENCES users ON DELETE CASCADE UNIQUE NOT NULL,
  slug VARCHAR(255) NOT NULL,
  headline VARCHAR(255) NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE bookings (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID REFERENCES users ON DELETE CASCADE,
  sitter_id UUID REFERENCES sitters,
  start_date date NOT NULL,
  end_date date NOT NULL,
  pets_ids UUID[] NOT NULL,
  status VARCHAR(15) NOT NULL DEFAULT 'created',
  total_amount_cents INT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE messages (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  booking_id UUID REFERENCES bookings ON DELETE CASCADE,
  sender_id UUID REFERENCES users ON DELETE CASCADE,
  receiver_id UUID REFERENCES users ON DELETE CASCADE,
  content TEXT NOT NULL,
  seen_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

所以:

  • 用户可以是一名保姆。
  • 预订有用户和保姆。
  • 邮件属于唯一的预订。

我想:

如果出现user_id,则sitter_idbooking_id返回预订的消息:

  • booking_id有效
  • 该预订ID与给定的user_idsitter_id或两者匹配。

所以我得到了:

SELECT m.*,
b.user_id, b.sitter_id
FROM bookings b
LEFT JOIN messages m
ON m.booking_id=b.id
WHERE b.id=$1 AND (b.user_id=$2 OR b.sitter_id=$3);

我想收到:

    如果预订不存在,
  • 什么
  • user_idsitter_id匹配
  • 没有任何内容
  • 预订ID字段,如果预订存在但没有消息

它运作正常,但在尝试不同的JOINS后,我看到了相同的结果。任何可能破坏的场景?

1 个答案:

答案 0 :(得分:6)

你是什么意思:

  

它运作正常,但在尝试不同的JOINS后,我看到了相同的结果。任何可能破坏的场景?

您似乎正在使用" distinct"在英语意义上,不是在SQL意义上,这在SQL问题中有点令人困惑。

你在加入什么?

  • 任何与其他桌子的左连接都应该没有效果,可能除了你的宠物桌子。
  • 如果找不到用户/保姆,则加入用户或参与者表可能会导致查询失效。
  

我想收到预订ID字段,如果预订存在但没有消息

如果没有预订信息,您选择列的方式将导致空的预订ID。

  • 考虑手动列出所有列

请参阅我的简化SQLFiddle http://sqlfiddle.com/#!15/8b976/2
请考虑澄清你的问题。