postgresql / sql-连接(双精度)两个表,并按第二个表的列排序

时间:2019-07-10 10:57:27

标签: sql postgresql

表格

任务:

id  message        assignor

11   33            909
32   13            5464
52   521           909

消息:

id    text        state

33    Merheba     NEW
43    Salam       READ
312   Olá         READ
521   hello       NEW
412   Hola        NEW
212   Hallo       READ
765   Saluton     READ

我有两个表: assignment message assignment 是指 message 。我要查询其 state 'NEW' 而其 assignor <909 assignment 中,或者它们在 assignment 中不存在。我需要按 assignor 对列表进行排序。

我已使用此查询来获取所有消息,但不确定是否可以对结果进行排序。

select * from message
       where 
         (id not in (select  message from assignment)
         or id in (select  message from assignment where assignee = 909)) 
         and state = 'NEW';

是否可以简化查询?我两次寻找消息。

结果必须是:

id    text        state

33    Merhaba     NEW
521   hello       NEW
412   Hola        NEW

前两行具有分配器(分配中为909),三行均为NEW

2 个答案:

答案 0 :(得分:1)

您的查询很好。我倾向于使用exists来写这样的逻辑:

select m.*
from message m
where m.state = 'NEW' and
      (exists (select 1 from assignment a where a.message = m.id and a.assignee = 909) or
       not exists (select 1 from assignment where a.message = m.id)
      );

如果邮件中没有多个assignee,则可以将其更改为:

select m.*
from message m
where m.state = 'NEW' and
      not exists (select 1
                  from assignment a
                  where a.message = m.id and a.assignee <> 909
                 );

编辑:

为了按assignor进行排序,您需要join中的该表:

select m.*
from message m left join
     assignment a
     on m.id = a.message
where m.state = 'NEW' and
      not exists (select 1
                  from assignment a
                  where a.message = m.id and a.assignee <> 909
                 )
order by a.assignor;

第二版也是如此。

您还可以将整个内容设为join

select m.*
from message m left join
     assignment a
     on m.id = a.message
where m.state = 'NEW' and
      (a.message is null or  -- no matches
       a.assignee = 909
      )
order by a.assignor;

答案 1 :(得分:1)

您的架构:

CREATE TABLE assignment(
  id INT,
  message INT,
  assignor INT
);
CREATE TABLE message(
  id INT,
  text VARCHAR(255),
  state VARCHAR(255)
);

您的测试数据:

INSERT INTO assignment (id, message, assignor) VALUES
  (11, 33, 909),
  (32, 13, 5464),
  (52, 521, 909);
INSERT INTO message (id, text, state) VALUES
  (33, 'Merheba', 'NEW'),
  (43, 'Salam', 'READ'),
  (312, 'Olá', 'READ'),
  (521, 'hello', 'NEW'),
  (412, 'Hola', 'NEW'),
  (212, 'Hallo', 'READ'),
  (765, 'Saluton', 'READ');

您的要求:

  

我要查询状态为“ NEW”且其分配者为909或分配中不存在的所有消息。我需要按分配器对列表进行排序。

您需要的查询:

SELECT message.*
FROM message
LEFT JOIN assignment ON message.id = assignment.message
WHERE message.state = 'NEW'
  AND (assignment.assignor = 909 OR assignment.assignor IS NULL)
ORDER BY assignment.assignor;

其结果:

id  | text    | state
----+---------+------
33  | Merheba | NEW
521 | hello   | NEW
412 | Hola    | NEW