在postgresql中有条件地从一个单独的表中选择一列



我有一个通知、事件和组织的表。通知有一个名为event-id的列,该列可以为null。我正在尝试选择通知,对于有事件的通知,使用organization.timezone,而对于没有事件的没有时区(或null(的通知。下面是一个表格的例子(去掉了不相关的字段(

通知表

id | message | event-id
0  |  "a"    | 0
1  |  "b"    | nil

事件表

id | org-id 
0  |  0    
1  |  1

组织表

id | timezone
0  |  "Eastern"    
1  |  "Other" 

我的查询应该返回

id | message | timezone
0  |  "a"    | "eastern"
1  |  "b"    | nil

我的尝试如下(翻译自clojure mileyql,如果有拼写错误,很抱歉(:

Select notifications.id, notifications.message, (case when notifications.event-id then organizations.timezone end) 
where (or (= notifications.event-id nil) 
(and (= notifications.event-id events.id)
(= events.org-id organizations.id))
end

但我有

我的查询应该返回

id | message | case
0  |  "a"    | "eastern"
1  |  "b"    | nil
1  |  "b"    | nil

我该如何解决这个问题,这样我就不会为每个事件id为null的通知获得重复值?

您翻译的SQL无效,因此很难说为什么会出现重复,但这里有一些有效的SQL,它会返回您想要的结果,希望您能将其翻译成原始格式。

设置

CREATE TABLE notifications (
"id" INTEGER,
"message" VARCHAR(3),
"event-id" INTEGER
);
INSERT INTO notifications
("id", "message", "event-id")
VALUES
('0', 'a', '0'),
('1', 'b', NULL);
CREATE TABLE events (
"id" INTEGER,
"org-id" INTEGER
);
INSERT INTO events
("id", "org-id")
VALUES
('0', '0'),
('1', '1');
CREATE TABLE organizations (
"id" INTEGER,
"timezone" VARCHAR(9)
);
INSERT INTO organizations
("id", "timezone")
VALUES
('0', 'Eastern'),
('1', 'Other');

查询

SELECT n.id, n.message, o.timezone
FROM notifications n
LEFT JOIN events e
ON e.id = n."event-id"
LEFT JOIN organizations o
ON o.id = e."org-id";

结果

| id  | message | timezone |
| --- | ------- | -------- |
| 0   | a       | Eastern  |
| 1   | b       |          |

DB Fiddle

最新更新